1 /* $NetBSD: rz.c,v 1.24 2009/03/14 15:36:12 dsl Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * @(#)rz.c 8.1 (Berkeley) 6/10/93
37 #include <lib/libsa/stand.h>
38 #include <lib/libkern/libkern.h>
39 #include <machine/dec_prom.h>
40 #include <machine/stdarg.h>
42 #include <sys/param.h>
43 #include <sys/disklabel.h>
48 #define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */
52 int sc_fd
; /* PROM file id */
53 int sc_ctlr
; /* controller number */
54 int sc_unit
; /* disk unit number */
55 int sc_part
; /* disk partition number */
56 struct disklabel sc_label
; /* disk label for this disk */
60 rzstrategy(void *devdata
, int rw
, daddr_t bn
, size_t reqcnt
, void *addr
, size_t *cnt
)
61 /* cnt: out: number of bytes transfered */
63 struct rz_softc
*sc
= (struct rz_softc
*)devdata
;
64 int part
= sc
->sc_part
;
65 struct partition
*pp
= &sc
->sc_label
.d_partitions
[part
];
72 * Partial-block transfers not handled.
74 if (reqcnt
& (DEV_BSIZE
- 1)) {
79 offset
+= pp
->p_offset
;
81 if (pp
->p_fstype
== FS_RAID
)
82 offset
+= RF_PROTECTED_SECTORS
;
85 * Convert from blocks to bytes.
89 if (callv
== &callvec
) {
90 /* No REX on this machine */
91 if (prom_lseek(sc
->sc_fd
, offset
, 0) < 0)
93 s
= prom_read(sc
->sc_fd
, addr
, reqcnt
);
95 s
= bootread (offset
/ 512, addr
, reqcnt
);
104 rzopen(struct open_file
*f
, ...)
106 int ctlr
, unit
, part
;
109 struct disklabel
*lp
;
114 static char device
[] = "rz(0,0,0)";
119 ctlr
= va_arg(ap
, int);
120 unit
= va_arg(ap
, int);
121 part
= va_arg(ap
, int);
123 if (unit
>= 8 || part
>= 8)
125 device
[5] = '0' + unit
;
126 /* NOTE: only support reads for now */
127 /* Another NOTE: bootinit on the TurboChannel doesn't look at
128 the device string - it's provided for compatibility with
129 the DS3100 PROMs. As a consequence, it may be possible to
130 boot from some other drive with these bootblocks on the 3100,
131 but will not be possible on any TurboChannel machine. */
133 if (callv
== &callvec
)
134 i
= prom_open(device
, 0);
136 i
= bootinit (device
);
138 printf("open failed\n");
142 sc
= alloc(sizeof(struct rz_softc
));
143 memset(sc
, 0, sizeof(struct rz_softc
));
144 f
->f_devdata
= (void *)sc
;
151 /* try to read disk label and partition table information */
153 lp
->d_secsize
= DEV_BSIZE
;
155 lp
->d_npartitions
= MAXPARTITIONS
;
156 lp
->d_partitions
[part
].p_offset
= 0;
157 lp
->d_partitions
[part
].p_size
= 0x7fffffff;
159 i
= rzstrategy(sc
, F_READ
, (daddr_t
)LABELSECTOR
, DEV_BSIZE
, buf
, &cnt
);
160 if (i
|| cnt
!= DEV_BSIZE
) {
161 /* printf("rz%d: error reading disk label\n", unit); */
164 msg
= getdisklabel(buf
, lp
);
166 /* If no label, just assume 0 and return */
170 if (part
>= lp
->d_npartitions
|| lp
->d_partitions
[part
].p_size
== 0) {
172 dealloc(sc
, sizeof(struct rz_softc
));
178 #ifndef LIBSA_NO_DEV_CLOSE
180 rzclose(struct open_file
*f
)
182 if (callv
== &callvec
)
183 prom_close(((struct rz_softc
*)f
->f_devdata
)->sc_fd
);
185 dealloc(f
->f_devdata
, sizeof(struct rz_softc
));
186 f
->f_devdata
= (void *)0;