1 /* $OpenBSD: ufs_disksubr.c,v 1.7 2023/04/10 04:21:20 jsg 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
sun_extended_sum(struct sun_disklabel * sl,void * end)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 strategy 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 *
readdisklabel(struct scsi_softc * sc,uint tgt,struct disklabel * lp)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 memcpy(lp->d_packname, slp->sl_text, sizeof(lp->d_packname));
153 lp->d_nsectors = slp->sl_nsectors;
154 lp->d_ntracks = slp->sl_ntracks;
155 lp->d_ncylinders = slp->sl_ncylinders;
156
157 secpercyl = slp->sl_nsectors * slp->sl_ntracks;
158 lp->d_secpercyl = secpercyl;
159 if (DL_GETDSIZE(lp) == 0)
160 DL_SETDSIZE(lp, (u_int64_t)secpercyl * slp->sl_ncylinders);
161 lp->d_version = 1;
162
163 memcpy(&lp->d_uid, &slp->sl_uid, sizeof(slp->sl_uid));
164
165 lp->d_acylinders = slp->sl_acylinders;
166
167 lp->d_npartitions = MAXPARTITIONS;
168
169 for (i = 0; i < 8; i++) {
170 spp = &slp->sl_part[i];
171 npp = &lp->d_partitions[i];
172 /* UniOS label uses blkoffset, not cyloffset */
173 DL_SETPOFFSET(npp, spp->sdkp_cyloffset);
174 DL_SETPSIZE(npp, spp->sdkp_nsectors);
175 if (DL_GETPSIZE(npp) == 0) {
176 npp->p_fstype = FS_UNUSED;
177 } else {
178 npp->p_fstype = i == 2 ? FS_UNUSED :
179 i == 1 ? FS_SWAP : FS_BSDFFS;
180 if (npp->p_fstype == FS_BSDFFS) {
181 /*
182 * The sun label does not store the FFS fields,
183 * so just set them with default values here.
184 */
185 npp->p_fragblock = 8 | 3
186 /* DISKLABELV1_FFS_FRAGBLOCK(2048, 8); */ ;
187 npp->p_cpg = 16;
188 }
189 }
190 }
191
192 /*
193 * XXX BandAid XXX
194 * UniOS rootfs sits on part c which don't begin at sect 0,
195 * and impossible to mount. Thus, make it usable as part b.
196 * XXX how to setup a swap partition on disks shared with UniOS???
197 */
198 if (slp->sl_rpm == 0 && DL_GETPOFFSET(&lp->d_partitions[2]) != 0) {
199 lp->d_partitions[1] = lp->d_partitions[2];
200 lp->d_partitions[1].p_fstype = FS_BSDFFS;
201 }
202
203 /* Clear "extended" partition info, tentatively */
204 for (i = 0; i < SUNXPART; i++) {
205 npp = &lp->d_partitions[i+8];
206 DL_SETPOFFSET(npp, 0);
207 DL_SETPSIZE(npp, 0);
208 npp->p_fstype = FS_UNUSED;
209 }
210
211 /* Check to see if there's an "extended" partition table
212 * SL_XPMAG partitions had checksums up to just before the
213 * (new) sl_types variable, while SL_XPMAGTYP partitions have
214 * checksums up to the just before the (new) sl_xxx1 variable.
215 */
216 if ((slp->sl_xpmag == SL_XPMAG &&
217 sun_extended_sum(slp, &slp->sl_types) == slp->sl_xpsum) ||
218 (slp->sl_xpmag == SL_XPMAGTYP &&
219 sun_extended_sum(slp, &slp->sl_xxx1) == slp->sl_xpsum)) {
220 /*
221 * There is. Copy over the "extended" partitions.
222 * This code parallels the loop for partitions a-h.
223 */
224 for (i = 0; i < SUNXPART; i++) {
225 spp = &slp->sl_xpart[i];
226 npp = &lp->d_partitions[i+8];
227 DL_SETPOFFSET(npp, spp->sdkp_cyloffset);
228 DL_SETPSIZE(npp, spp->sdkp_nsectors);
229 if (DL_GETPSIZE(npp) == 0) {
230 npp->p_fstype = FS_UNUSED;
231 continue;
232 }
233 npp->p_fstype = FS_BSDFFS;
234 if (npp->p_fstype == FS_BSDFFS) {
235 npp->p_fragblock = 8 | 3
236 /* DISKLABELV1_FFS_FRAGBLOCK(2048, 8); */ ;
237 npp->p_cpg = 16;
238 }
239 }
240 if (slp->sl_xpmag == SL_XPMAGTYP) {
241 for (i = 0; i < MAXPARTITIONS; i++) {
242 npp = &lp->d_partitions[i];
243 npp->p_fstype = slp->sl_types[i];
244 npp->p_fragblock = slp->sl_fragblock[i];
245 npp->p_cpg = slp->sl_cpg[i];
246 }
247 }
248 }
249
250 lp->d_checksum = 0;
251 lp->d_checksum = dkcksum(lp);
252
253 return NULL;
254 }
255