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