1 /* $NetBSD: read.c,v 1.3 2008/04/28 20:23:15 martin Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julian Coleman, Waldi Ravens and Leo Weppelman.
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
41 #include <sys/ioctl.h>
44 * Read AHDI partitions from disk.
47 ahdi_readlabel (struct ahdi_ptable
*ptable
, char *diskname
, int flags
)
52 if (!(fd
= openraw (diskname
, O_RDONLY
)))
55 if ((dl
= read_dl (fd
)) == NULL
) {
60 if (dl
->d_secsize
!= AHDI_BSIZE
) {
65 if ((rv
= check_magic(fd
, LABELSECTOR
, flags
)) < 0) {
70 bzero ((void *) ptable
, sizeof (struct ahdi_ptable
));
72 if ((rv
= read_rsec (fd
, ptable
, AHDI_BBLOCK
, AHDI_BBLOCK
, flags
))
78 if (dl
->d_secperunit
!= ptable
->secperunit
) {
79 if (flags
& AHDI_IGN_SPU
)
80 ptable
->secperunit
= dl
->d_secperunit
;
87 ptable
->nsectors
= dl
->d_nsectors
;
88 ptable
->ntracks
= dl
->d_ntracks
;
89 ptable
->ncylinders
= dl
->d_ncylinders
;
90 ptable
->secpercyl
= dl
->d_secpercyl
;
92 assign_letters (ptable
);
99 * Read AHDI partitions from root sector/auxillary root sector.
102 read_rsec (int fd
, struct ahdi_ptable
*ptable
, u_int rsec
, u_int esec
, int flags
)
104 struct ahdi_part
*part
, *end
;
105 struct ahdi_root
*root
;
106 u_int16_t cksum
, newcksum
;
109 if ((root
= disk_read (fd
, rsec
, 1)) == NULL
) {
113 if (rsec
== AHDI_BBLOCK
) {
114 end
= &root
->ar_parts
[AHDI_MAXRPD
];
115 if (root
->ar_checksum
) {
116 cksum
= root
->ar_checksum
;
117 root
->ar_checksum
= 0;
118 newcksum
= ahdi_cksum (root
);
119 if ((cksum
!= newcksum
) && !(flags
& AHDI_IGN_CKSUM
)) {
124 ptable
->secperunit
=root
->ar_hdsize
;
126 end
= &root
->ar_parts
[AHDI_MAXARPD
];
127 for (part
= root
->ar_parts
; part
< end
; ++part
) {
129 printf ("Found partitions at sector %u:\n", rsec
);
130 printf (" flags : %02x\n", part
->ap_flg
);
131 printf (" id : %c%c%c\n", part
->ap_id
[0], part
->ap_id
[1],
133 printf (" start : %u\n", part
->ap_st
);
134 printf (" size : %u\n", part
->ap_size
);
136 if (!(part
->ap_flg
& 0x01)) {
137 if ((part
->ap_id
[0] || part
->ap_id
[1] ||
138 part
->ap_id
[2]) && (flags
& AHDI_IGN_EXISTS
))
139 part
->ap_flg
&= 0x01;
144 if (AHDI_MKPID (part
->ap_id
[0], part
->ap_id
[1],
145 part
->ap_id
[2]) == AHDI_PID_XGM
) {
146 u_int offs
= part
->ap_st
+ esec
;
147 if ((rv
= read_rsec (fd
, ptable
, offs
,
148 esec
== AHDI_BBLOCK
? offs
: esec
, flags
)) < 0) {
153 /* Attempt to check for junk values */
154 if (((part
->ap_st
+ rsec
) > ptable
->secperunit
||
155 (part
->ap_st
+ rsec
+ part
->ap_size
-1) >
156 ptable
->secperunit
)) {
157 if (flags
& AHDI_IGN_EXT
) {
158 /* Fake previous partition */
159 ptable
->parts
[ptable
->nparts
].id
[0] =
161 ptable
->parts
[ptable
->nparts
].id
[1] =
163 ptable
->parts
[ptable
->nparts
].id
[2] =
170 ptable
->parts
[ptable
->nparts
].flag
= part
->ap_flg
;
171 ptable
->parts
[ptable
->nparts
].id
[0] = part
->ap_id
[0];
172 ptable
->parts
[ptable
->nparts
].id
[1] = part
->ap_id
[1];
173 ptable
->parts
[ptable
->nparts
].id
[2] = part
->ap_id
[2];
174 ptable
->parts
[ptable
->nparts
].root
= rsec
;
175 ptable
->parts
[ptable
->nparts
].start
=
177 ptable
->parts
[ptable
->nparts
].size
= part
->ap_size
;
182 if (ptable
->nparts
|| FORCE_AHDI
)
189 * Read a sector from the disk.
192 disk_read (fd
, start
, count
)
202 size
= count
* DEV_BSIZE
;
203 offset
= start
* DEV_BSIZE
;
205 if ((buffer
= malloc (size
)) == NULL
)
208 if (lseek (fd
, offset
, SEEK_SET
) != offset
) {
212 if (read (fd
, buffer
, size
) != size
) {
220 * Assign NetBSD drive letters to partitions
223 assign_letters (struct ahdi_ptable
*ptable
)
225 int i
, have_root
, pno
;
233 for (i
= 0; i
< ptable
->nparts
; i
++) {
234 while (pno
== ROOT_PART
|| pno
== SWAP_PART
|| pno
== RAW_PART
)
236 pid
= AHDI_MKPID (ptable
->parts
[i
].id
[0],
237 ptable
->parts
[i
].id
[1], ptable
->parts
[i
].id
[2]);
238 if (!have_root
&& pid
== AHDI_PID_NBD
) {
239 ptable
->parts
[i
].letter
= ROOT_PART
;
241 } else if (pid
== AHDI_PID_SWP
)
242 ptable
->parts
[i
].letter
= SWAP_PART
;
244 ptable
->parts
[i
].letter
= pno
;
251 * Read disklabel for disk.
256 struct disklabel
*dl
;
258 if ((dl
= malloc (sizeof (struct disklabel
))) == NULL
) {
262 if (ioctl (fd
, DIOCGDINFO
, dl
) < 0) {