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 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 * 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