Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / atari / stand / ahdilabel / read.c
blob54800f164e4b439ebbdb14c70214eb825b1b8b02
1 /* $NetBSD: read.c,v 1.3 2008/04/28 20:23:15 martin Exp $ */
3 /*
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
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
12 * are met:
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.
32 #include "privahdi.h"
33 #include <fcntl.h>
34 #ifdef DEBUG
35 #include <stdio.h>
36 #endif
37 #include <stdlib.h>
38 #include <strings.h>
39 #include <unistd.h>
40 #include <sys/dkio.h>
41 #include <sys/ioctl.h>
44 * Read AHDI partitions from disk.
46 int
47 ahdi_readlabel (struct ahdi_ptable *ptable, char *diskname, int flags)
49 int fd, rv;
50 struct disklabel *dl;
52 if (!(fd = openraw (diskname, O_RDONLY)))
53 return (-1);
55 if ((dl = read_dl (fd)) == NULL) {
56 close (fd);
57 return (-1);
60 if (dl->d_secsize != AHDI_BSIZE) {
61 close (fd);
62 return (-2);
65 if ((rv = check_magic(fd, LABELSECTOR, flags)) < 0) {
66 close (fd);
67 return (rv);
70 bzero ((void *) ptable, sizeof (struct ahdi_ptable));
72 if ((rv = read_rsec (fd, ptable, AHDI_BBLOCK, AHDI_BBLOCK, flags))
73 < 0) {
74 close (fd);
75 return (rv);
78 if (dl->d_secperunit != ptable->secperunit) {
79 if (flags & AHDI_IGN_SPU)
80 ptable->secperunit = dl->d_secperunit;
81 else {
82 close (fd);
83 return (-6);
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);
94 close (fd);
95 return (1);
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;
107 int rv;
109 if ((root = disk_read (fd, rsec, 1)) == NULL) {
110 return (-1);
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)) {
120 free (root);
121 return (-4);
124 ptable->secperunit=root->ar_hdsize;
125 } else
126 end = &root->ar_parts[AHDI_MAXARPD];
127 for (part = root->ar_parts; part < end; ++part) {
128 #ifdef DEBUG
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],
132 part->ap_id[2]);
133 printf (" start : %u\n", part->ap_st);
134 printf (" size : %u\n", part->ap_size);
135 #endif
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;
140 else
141 continue;
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) {
149 free (root);
150 return (rv);
152 } else {
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] =
160 part->ap_id[0];
161 ptable->parts[ptable->nparts].id[1] =
162 part->ap_id[1];
163 ptable->parts[ptable->nparts].id[2] =
164 part->ap_id[2];
165 } else {
166 free (root);
167 return (-5);
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 =
176 part->ap_st + rsec;
177 ptable->parts[ptable->nparts].size = part->ap_size;
178 ptable->nparts++;
181 free (root);
182 if (ptable->nparts || FORCE_AHDI)
183 return (1);
184 else
185 return (-3);
189 * Read a sector from the disk.
191 void *
192 disk_read (fd, start, count)
193 int fd;
194 u_int start,
195 count;
197 void *buffer;
198 off_t offset;
199 size_t size;
202 size = count * DEV_BSIZE;
203 offset = start * DEV_BSIZE;
205 if ((buffer = malloc (size)) == NULL)
206 return (NULL);
208 if (lseek (fd, offset, SEEK_SET) != offset) {
209 free (buffer);
210 return (NULL);
212 if (read (fd, buffer, size) != size) {
213 free (buffer);
214 return (NULL);
216 return (buffer);
220 * Assign NetBSD drive letters to partitions
222 void
223 assign_letters (struct ahdi_ptable *ptable)
225 int i, have_root, pno;
226 u_int32_t pid;
228 #define ROOT_PART 0
230 have_root = 0;
231 pno = 0;
233 for (i = 0; i < ptable->nparts; i++) {
234 while (pno == ROOT_PART || pno == SWAP_PART || pno == RAW_PART)
235 pno++;
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;
240 have_root = 1;
241 } else if (pid == AHDI_PID_SWP)
242 ptable->parts[i].letter = SWAP_PART;
243 else {
244 ptable->parts[i].letter = pno;
245 pno++;
251 * Read disklabel for disk.
253 struct disklabel *
254 read_dl (int fd)
256 struct disklabel *dl;
258 if ((dl = malloc (sizeof (struct disklabel))) == NULL) {
259 return (NULL);
262 if (ioctl (fd, DIOCGDINFO, dl) < 0) {
263 free (dl);
264 return (NULL);
266 return (dl);