xref: /openbsd-src/sys/arch/luna88k/stand/boot/ufs_disksubr.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: ufs_disksubr.c,v 1.4 2013/11/05 00:51:58 krw Exp $	*/
2 /*	$NetBSD: ufs_disksubr.c,v 1.2 2013/01/14 01:37:57 tsutsui Exp $	*/
3 
4 /*
5  * Copyright (c) 1992 OMRON Corporation.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * OMRON Corporation.
9  *
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.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)ufs_disksubr.c	8.1 (Berkeley) 6/10/93
39  */
40 /*
41  * Copyright (c) 1992, 1993
42  *	The Regents of the University of California.  All rights reserved.
43  *
44  * This code is derived from software contributed to Berkeley by
45  * OMRON Corporation.
46  *
47  * Redistribution and use in source and binary forms, with or without
48  * modification, are permitted provided that the following conditions
49  * are met:
50  * 1. Redistributions of source code must retain the above copyright
51  *    notice, this list of conditions and the following disclaimer.
52  * 2. Redistributions in binary form must reproduce the above copyright
53  *    notice, this list of conditions and the following disclaimer in the
54  *    documentation and/or other materials provided with the distribution.
55  * 3. Neither the name of the University nor the names of its contributors
56  *    may be used to endorse or promote products derived from this software
57  *    without specific prior written permission.
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69  * SUCH DAMAGE.
70  *
71  *	@(#)ufs_disksubr.c	8.1 (Berkeley) 6/10/93
72  */
73 
74 /*
75  * ufs_disksubr.c -- disk utility routines
76  * by A.Fujita, FEB-26-1992
77  */
78 
79 #include <sys/param.h>
80 #include <sys/disklabel.h>
81 #include <dev/sun/disklabel.h>
82 #include <luna88k/stand/boot/samachdep.h>
83 #include <luna88k/stand/boot/scsireg.h>
84 
85 #define	BBSIZE 8192
86 #define	LABEL_SIZE BBSIZE
87 u_char lbl_buff[LABEL_SIZE];
88 
89 /*
90  * Given a struct sun_disklabel, assume it has an extended partition
91  * table and compute the correct value for sl_xpsum.
92  */
93 static __inline u_int
94 sun_extended_sum(struct sun_disklabel *sl, void *end)
95 {
96 	u_int sum, *xp, *ep;
97 
98 	xp = (u_int *)&sl->sl_xpmag;
99 	ep = (u_int *)end;
100 
101 	sum = 0;
102 	for (; xp < ep; xp++)
103 		sum += *xp;
104 	return (sum);
105 }
106 
107 /*
108  * Attempt to read a disk label from a device
109  * using the indicated stategy routine.
110  * The label must be partly set up before this:
111  * secpercyl and anything required in the strategy routine
112  * (e.g., sector size) must be filled in before calling us.
113  * Returns null on success and an error string on failure.
114  */
115 char *
116 readdisklabel(struct scsi_softc *sc, uint tgt, struct disklabel *lp)
117 {
118 	u_char *bp = lbl_buff;
119 	struct sun_disklabel *slp;
120 	struct partition *npp;
121 	struct sun_dkpart *spp;
122 	u_short cksum = 0, *sp1, *sp2;
123 	int i, secpercyl;
124 	static struct scsi_generic_cdb cdb = {
125 		6,
126 		{ CMD_READ, 0, 0, 0, 1, 0 }
127 	};
128 
129 	if (DL_GETDSIZE(lp) == 0)
130 		DL_SETDSIZE(lp, 0x1fffffff);
131 	lp->d_npartitions = 1;
132 	if (DL_GETPSIZE(&lp->d_partitions[0]) == 0)
133 		DL_SETPSIZE(&lp->d_partitions[0], 0x1fffffff);
134 	DL_SETPSIZE(&lp->d_partitions[0], 0);
135 
136 	if (scsi_immed_command(sc, tgt, 0, &cdb, bp, DEV_BSIZE) != 0)
137 		return "I/O error";
138 
139 	slp = (struct sun_disklabel *)bp;
140 	if (slp->sl_magic != SUN_DKMAGIC)
141 		return "no disk label";
142 
143 	sp1 = (u_short *)slp;
144 	sp2 = (u_short *)(slp + 1);
145 	while (sp1 < sp2)
146 		cksum ^= *sp1++;
147 	if (cksum != 0)
148 		return "disk label corrupted";
149 
150 	lp->d_magic = DISKMAGIC;
151 	lp->d_magic2 = DISKMAGIC;
152 	lp->d_flags = D_VENDOR;
153 	memcpy(lp->d_packname, slp->sl_text, sizeof(lp->d_packname));
154 	lp->d_nsectors = slp->sl_nsectors;
155 	lp->d_ntracks = slp->sl_ntracks;
156 	lp->d_ncylinders = slp->sl_ncylinders;
157 
158 	secpercyl = slp->sl_nsectors * slp->sl_ntracks;
159 	lp->d_secpercyl = secpercyl;
160 	if (DL_GETDSIZE(lp) == 0)
161 		DL_SETDSIZE(lp, (u_int64_t)secpercyl * slp->sl_ncylinders);
162 	lp->d_version = 1;
163 
164 	memcpy(&lp->d_uid, &slp->sl_uid, sizeof(slp->sl_uid));
165 
166 	lp->d_acylinders = slp->sl_acylinders;
167 
168 	lp->d_npartitions = MAXPARTITIONS;
169 	/* These are as defined in <ufs/ffs/fs.h> */
170 	lp->d_bbsize = BBSIZE;    /* XXX */
171 	lp->d_sbsize = BBSIZE;    /* XXX */
172 
173 	for (i = 0; i < 8; i++) {
174 		spp = &slp->sl_part[i];
175 		npp = &lp->d_partitions[i];
176 		/* UniOS label uses blkoffset, not cyloffset */
177 		DL_SETPOFFSET(npp, spp->sdkp_cyloffset);
178 		DL_SETPSIZE(npp, spp->sdkp_nsectors);
179 		if (DL_GETPSIZE(npp) == 0) {
180 			npp->p_fstype = FS_UNUSED;
181 		} else {
182 			npp->p_fstype = i == 2 ? FS_UNUSED :
183 			    i == 1 ? FS_SWAP : FS_BSDFFS;
184 			if (npp->p_fstype == FS_BSDFFS) {
185 				/*
186 				 * The sun label does not store the FFS fields,
187 				 * so just set them with default values here.
188 				 */
189 				npp->p_fragblock = 8 | 3
190 				    /* DISKLABELV1_FFS_FRAGBLOCK(2048, 8); */ ;
191 				npp->p_cpg = 16;
192 			}
193 		}
194 	}
195 
196 	/*
197 	 * XXX BandAid XXX
198 	 * UniOS rootfs sits on part c which don't begin at sect 0,
199 	 * and impossible to mount.  Thus, make it usable as part b.
200 	 * XXX how to setup a swap partition on disks shared with UniOS???
201 	 */
202 	if (slp->sl_rpm == 0 && DL_GETPOFFSET(&lp->d_partitions[2]) != 0) {
203 		lp->d_partitions[1] = lp->d_partitions[2];
204 		lp->d_partitions[1].p_fstype = FS_BSDFFS;
205 	}
206 
207 	/* Clear "extended" partition info, tentatively */
208 	for (i = 0; i < SUNXPART; i++) {
209 		npp = &lp->d_partitions[i+8];
210 		DL_SETPOFFSET(npp, 0);
211 		DL_SETPSIZE(npp, 0);
212 		npp->p_fstype = FS_UNUSED;
213 	}
214 
215 	/* Check to see if there's an "extended" partition table
216 	 * SL_XPMAG partitions had checksums up to just before the
217 	 * (new) sl_types variable, while SL_XPMAGTYP partitions have
218 	 * checksums up to the just before the (new) sl_xxx1 variable.
219 	 */
220 	if ((slp->sl_xpmag == SL_XPMAG &&
221 	    sun_extended_sum(slp, &slp->sl_types) == slp->sl_xpsum) ||
222 	    (slp->sl_xpmag == SL_XPMAGTYP &&
223 	    sun_extended_sum(slp, &slp->sl_xxx1) == slp->sl_xpsum)) {
224 		/*
225 		 * There is.  Copy over the "extended" partitions.
226 		 * This code parallels the loop for partitions a-h.
227 		 */
228 		for (i = 0; i < SUNXPART; i++) {
229 			spp = &slp->sl_xpart[i];
230 			npp = &lp->d_partitions[i+8];
231 			DL_SETPOFFSET(npp, spp->sdkp_cyloffset);
232 			DL_SETPSIZE(npp, spp->sdkp_nsectors);
233 			if (DL_GETPSIZE(npp) == 0) {
234 				npp->p_fstype = FS_UNUSED;
235 				continue;
236 			}
237 			npp->p_fstype = FS_BSDFFS;
238 			if (npp->p_fstype == FS_BSDFFS) {
239 				npp->p_fragblock = 8 | 3
240 				    /* DISKLABELV1_FFS_FRAGBLOCK(2048, 8); */ ;
241 				npp->p_cpg = 16;
242 			}
243 		}
244 		if (slp->sl_xpmag == SL_XPMAGTYP) {
245 			for (i = 0; i < MAXPARTITIONS; i++) {
246 				npp = &lp->d_partitions[i];
247 				npp->p_fstype = slp->sl_types[i];
248 				npp->p_fragblock = slp->sl_fragblock[i];
249 				npp->p_cpg = slp->sl_cpg[i];
250 			}
251 		}
252 	}
253 
254 	lp->d_checksum = 0;
255 	lp->d_checksum = dkcksum(lp);
256 
257 	return NULL;
258 }
259