1 /* $NetBSD: disk.c,v 1.3 2005/12/11 12:16:41 christos 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 * @(#)disk.c 8.1 (Berkeley) 6/10/93
37 #include <lib/libsa/stand.h>
38 #include <machine/stdarg.h>
40 #include <sys/param.h>
41 #include <sys/disklabel.h>
43 #include <dev/arcbios/arcbios.h>
48 #define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */
50 extern const struct arcbios_fv
*ARCBIOS
;
53 u_long sc_fd
; /* ARCBIOS file id */
54 int sc_part
; /* disk partition number */
55 struct disklabel sc_label
; /* disk label for this disk */
59 diskstrategy(void *devdata
, int rw
, daddr_t bn
, size_t reqcnt
, void *addr
,
62 struct disk_softc
*sc
= (struct disk_softc
*)devdata
;
63 int part
= sc
->sc_part
;
64 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 error
= (*ARCBIOS
->Seek
)(sc
->sc_fd
, &offset
, 0);
90 if (error
!= ARCBIOS_ESUCCESS
)
92 error
= (*ARCBIOS
->Read
)(sc
->sc_fd
, addr
, reqcnt
, &count
);
93 if (error
!= ARCBIOS_ESUCCESS
)
101 diskopen(struct open_file
*f
, ...)
105 struct disk_softc
*sc
;
106 struct disklabel
*lp
;
108 char *msg
, buf
[DEV_BSIZE
];
119 device
= va_arg(ap
, char *);
122 * For NetBSD/sgimips, since we use the SGI partition map directly,
123 * we fake an in-core NetBSD disklabel with offset of 0.
125 * For NetBSD/arc, there is a MBR partition map on the disk, which we
126 * then expect to find a NetBSD disklabel within the MBR partition.
127 * We require that the kernel be located in first partition in the
128 * NetBSD disklabel, because we have not other way to represent the
133 if (part
>= MAXPARTITIONS
)
136 error
= (*ARCBIOS
->Open
)(device
, 0, &fd
);
138 printf("diskopen: open failed, errno = %d\n", error
);
142 sc
= alloc(sizeof(struct disk_softc
));
143 memset(sc
, 0, sizeof(struct disk_softc
));
144 f
->f_devdata
= (void *)sc
;
149 /* try to read disk label and partition table information */
151 lp
->d_secsize
= DEV_BSIZE
;
153 lp
->d_npartitions
= MAXPARTITIONS
;
154 lp
->d_partitions
[part
].p_offset
= 0;
155 lp
->d_partitions
[part
].p_size
= 0x7fffffff;
158 error
= diskstrategy(sc
, F_READ
, (daddr_t
)LABELSECTOR
, DEV_BSIZE
,
160 if (error
|| cnt
!= DEV_BSIZE
) {
161 printf("%s: can't read disklabel, errno = %d\n",
163 dealloc(sc
, sizeof(struct disk_softc
));
166 msg
= getdisklabel(buf
, lp
);
168 /* If no label, just assume 0 and return */
173 * On arc, we can't open whole disk, but can open each partition with
174 * OSLOADPARTITION like scsi(0)disk(0)rdisk()partition(1) etc.
175 * Thus, we don't have to add offset of the MBR partition.
177 /* XXX magic: partition 2 is whole NetBSD partition */
178 mbrp_off
= lp
->d_partitions
[2].p_offset
;
179 for (i
= 0; i
< MAXPARTITIONS
; i
++) {
180 if (lp
->d_partitions
[i
].p_fstype
!= FS_UNUSED
&&
181 lp
->d_partitions
[i
].p_offset
>= mbrp_off
)
182 lp
->d_partitions
[i
].p_offset
-= mbrp_off
;
185 if (part
>= lp
->d_npartitions
||
186 lp
->d_partitions
[part
].p_fstype
== FS_UNUSED
||
187 lp
->d_partitions
[part
].p_size
== 0) {
188 dealloc(sc
, sizeof(struct disk_softc
));
195 #ifndef LIBSA_NO_DEV_CLOSE
197 diskclose(struct open_file
*f
)
200 (*ARCBIOS
->Close
)(((struct disk_softc
*)(f
->f_devdata
))->sc_fd
);
201 dealloc(f
->f_devdata
, sizeof(struct disk_softc
));