1/* $NetBSD: blkdev.c,v 1.5 2009/01/12 07:30:45 tsutsui Exp $ */
2
3/*
4 * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 *    must display the following acknowledgement:
16 *      This product includes software developed by Christopher G. Demetriou
17 *	for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Copyright (c) 1992, 1993
35 *	The Regents of the University of California.  All rights reserved.
36 *
37 * This code is derived from software contributed to Berkeley by
38 * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 *    notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 *    notice, this list of conditions and the following disclaimer in the
47 *    documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 *    may be used to endorse or promote products derived from this software
50 *    without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 *	@(#)rz.c	8.1 (Berkeley) 6/10/93
65 */
66
67#include <lib/libsa/stand.h>
68#include <lib/libkern/libkern.h>
69
70#include <sys/param.h>
71#include <sys/disklabel.h>
72
73#include "stand/common/cfe_api.h"
74
75#include "stand/common/common.h"
76#include "blkdev.h"
77
78/*
79 * If BOOTXX_FS_TYPE is defined, we'll try to find and use the first
80 * partition with that type mentioned in the disklabel, else default to
81 * using block 0.
82 *
83 * The old boot blocks used to look for a file system starting at block
84 * 0.  It's not immediately obvious that change here is necessary or good,
85 * so for now we don't bother looking for the specific type.
86 */
87#undef BOOTXX_FS_TYPE
88
89int		blkdev_is_open;
90u_int32_t	blkdev_part_offset;
91
92/*
93 * Since we have only one device, and want to squeeze space, we just
94 * short-circuit devopen() to do the disk open as well.
95 *
96 * Devopen is supposed to decode the string 'fname', open the device,
97 * and make 'file' point to the remaining file name.  Since we don't
98 * do any device munging, we can just set *file to fname.
99 */
100int
101devopen(struct open_file *f, const char *fname, char **file)
102	/* file:	 out */
103{
104#if defined(BOOTXX_FS_TYPE)
105	int i;
106	size_t cnt;
107	char *msg, buf[DEV_BSIZE];
108	struct disklabel l;
109#endif /* defined(BOOTXX_FS_TYPE) */
110
111	if (blkdev_is_open) {
112		return (EBUSY);
113	    }
114
115	*file = (char *)fname;
116
117#if 0
118	f->f_devdata = NULL;			/* no point */
119#endif
120
121	/* Try to read disk label and partition table information. */
122	blkdev_part_offset = 0;
123#if defined(BOOTXX_FS_TYPE)
124
125	i = diskstrategy(NULL, F_READ,
126	    (daddr_t)LABELSECTOR, DEV_BSIZE, buf, &cnt);
127	if (i || cnt != DEV_BSIZE) {
128		return (ENXIO);
129	}
130	msg = getdisklabel(buf, &l);
131	if (msg == NULL) {
132		/*
133		 * there's a label.  find the first partition of the
134		 * type we want and use its offset.  if none are
135		 * found, we just use offset 0.
136		 */
137		for (i = 0; i < l.d_npartitions; i++) {
138			if (l.d_partitions[i].p_fstype == BOOTXX_FS_TYPE) {
139				blkdev_part_offset = l.d_partitions[i].p_offset;
140				break;
141			}
142		}
143	} else {
144		/* just use offset 0; it's already set that way */
145	}
146#endif /* defined(BOOTXX_FS_TYPE) */
147
148	blkdev_is_open = 1;
149	return (0);
150}
151
152int
153blkdevstrategy(void *devdata, int rw, daddr_t bn, size_t reqcnt, void *addrvoid, size_t *cnt)
154	/* cnt:	 out: number of bytes transfered */
155{
156	unsigned char *addr = addrvoid;
157	int res;
158
159#if !defined(LIBSA_NO_TWIDDLE)
160	twiddle();
161#endif
162
163	/* Partial-block transfers not handled. */
164	if (reqcnt & (DEV_BSIZE - 1)) {
165		*cnt = 0;
166		return (EINVAL);
167	}
168	res = cfe_readblk(booted_dev_fd,(bn+blkdev_part_offset)*DEV_BSIZE,addr,reqcnt);
169	if (res < 0) return EIO;
170
171	*cnt = res;
172	return (0);
173}
174
175#if !defined(LIBSA_NO_FS_CLOSE)
176int
177blkdevclose(struct open_file *f)
178{
179
180	blkdev_is_open = 0;
181	return (0);
182}
183#endif /* !defined(LIBSA_NO_FS_CLOSE) */
184