1 1.25 jdolecek /* $NetBSD: dkwedge_bsdlabel.c,v 1.25 2020/04/11 16:00:34 jdolecek Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.1 thorpej * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe. 9 1.1 thorpej * 10 1.1 thorpej * Redistribution and use in source and binary forms, with or without 11 1.1 thorpej * modification, are permitted provided that the following conditions 12 1.1 thorpej * are met: 13 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.1 thorpej * notice, this list of conditions and the following disclaimer. 15 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.1 thorpej * documentation and/or other materials provided with the distribution. 18 1.1 thorpej * 19 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.1 thorpej */ 31 1.1 thorpej 32 1.1 thorpej /* 33 1.1 thorpej * Adapted from kern/subr_disk_mbr.c: 34 1.1 thorpej * 35 1.1 thorpej * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 36 1.1 thorpej * All rights reserved. 37 1.3 perry * 38 1.1 thorpej * Redistribution and use in source and binary forms, with or without 39 1.1 thorpej * modification, are permitted provided that the following conditions 40 1.1 thorpej * are met: 41 1.3 perry * 1. Redistributions of source code must retain the above copyright 42 1.1 thorpej * notice, this list of conditions and the following disclaimer. 43 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 44 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 45 1.1 thorpej * documentation and/or other materials provided with the distribution. 46 1.1 thorpej * 3. Neither the name of the University nor the names of its contributors 47 1.1 thorpej * may be used to endorse or promote products derived from this software 48 1.1 thorpej * without specific prior written permission. 49 1.3 perry * 50 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 1.3 perry * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 1.1 thorpej * SUCH DAMAGE. 61 1.1 thorpej * 62 1.1 thorpej * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 63 1.1 thorpej */ 64 1.1 thorpej 65 1.1 thorpej /* 66 1.1 thorpej * 4.4BSD disklabel support for disk wedges 67 1.1 thorpej * 68 1.1 thorpej * Here is the basic search algorithm in use here: 69 1.1 thorpej * 70 1.1 thorpej * For historical reasons, we scan for x86-style MBR partitions looking 71 1.1 thorpej * for a MBR_PTYPE_NETBSD (or MBR_PTYPE_386BSD) partition. The first 72 1.1 thorpej * 4.4BSD disklabel found in the 2nd sector of such a partition is used. 73 1.1 thorpej * We assume that the 4.4BSD disklabel describes all partitions on the 74 1.1 thorpej * disk; we do not use any partition information from the MBR partition 75 1.1 thorpej * table. 76 1.1 thorpej * 77 1.1 thorpej * If that fails, then we fall back on a table of known locations for 78 1.1 thorpej * various platforms. 79 1.1 thorpej */ 80 1.1 thorpej 81 1.1 thorpej #include <sys/cdefs.h> 82 1.25 jdolecek __KERNEL_RCSID(0, "$NetBSD: dkwedge_bsdlabel.c,v 1.25 2020/04/11 16:00:34 jdolecek Exp $"); 83 1.6 martin 84 1.1 thorpej #include <sys/param.h> 85 1.11 martin #ifdef _KERNEL 86 1.1 thorpej #include <sys/systm.h> 87 1.11 martin #endif 88 1.1 thorpej #include <sys/proc.h> 89 1.1 thorpej #include <sys/errno.h> 90 1.1 thorpej #include <sys/disk.h> 91 1.1 thorpej #include <sys/vnode.h> 92 1.25 jdolecek #include <sys/buf.h> 93 1.1 thorpej 94 1.1 thorpej #include <sys/bootblock.h> 95 1.1 thorpej #include <sys/disklabel.h> 96 1.1 thorpej 97 1.1 thorpej #define BSD44_MBR_LABELSECTOR 1 98 1.1 thorpej 99 1.1 thorpej #define DISKLABEL_SIZE(x) \ 100 1.1 thorpej (offsetof(struct disklabel, d_partitions) + \ 101 1.1 thorpej (sizeof(struct partition) * (x))) 102 1.1 thorpej 103 1.1 thorpej /* 104 1.1 thorpej * Note the smallest MAXPARTITIONS was 8, so we allow a disklabel 105 1.1 thorpej * that size to be locted at the end of the sector. 106 1.1 thorpej */ 107 1.1 thorpej #define DISKLABEL_MINSIZE DISKLABEL_SIZE(8) 108 1.1 thorpej 109 1.1 thorpej /* 110 1.1 thorpej * Table of known platform-specific disklabel locations. 111 1.1 thorpej */ 112 1.1 thorpej static const struct disklabel_location { 113 1.1 thorpej daddr_t label_sector; /* sector containing label */ 114 1.1 thorpej size_t label_offset; /* byte offset of label in sector */ 115 1.1 thorpej } disklabel_locations[] = { 116 1.1 thorpej { 0, 0 }, /* mvme68k, next68k */ 117 1.1 thorpej { 0, 64 }, /* algor, alpha, amiga, amigappc, evbmips, evbppc, 118 1.1 thorpej luna68k, mac68k, macppc, news68k, newsmips, 119 1.1 thorpej pc532, pdp11, pmax, vax, x68k */ 120 1.1 thorpej { 0, 128 }, /* sparc, sun68k */ 121 1.18 skrll { 1, 0 }, /* amd64, arc, arm, bebox, cobalt, evbppc, hppa, 122 1.1 thorpej hpcarm, hpcmips, i386, ibmnws, mipsco, mvmeppc, 123 1.19 martin ofppc, playstation2, pmppc, prep, sandpoint, 124 1.13 scw sbmips, sgimips, sh3 */ 125 1.1 thorpej /* XXX atari is weird */ 126 1.1 thorpej { 2, 0 }, /* cesfic, hp300 */ 127 1.1 thorpej 128 1.1 thorpej { -1, 0 }, 129 1.1 thorpej }; 130 1.1 thorpej 131 1.1 thorpej #define SCAN_CONTINUE 0 132 1.1 thorpej #define SCAN_FOUND 1 133 1.1 thorpej #define SCAN_ERROR 2 134 1.1 thorpej 135 1.1 thorpej typedef struct mbr_args { 136 1.1 thorpej struct disk *pdk; 137 1.1 thorpej struct vnode *vp; 138 1.25 jdolecek struct buf *bp; 139 1.1 thorpej int error; 140 1.23 mlelstv uint32_t secsize; 141 1.1 thorpej } mbr_args_t; 142 1.1 thorpej 143 1.1 thorpej static const char * 144 1.1 thorpej bsdlabel_fstype_to_str(uint8_t fstype) 145 1.1 thorpej { 146 1.1 thorpej const char *str; 147 1.1 thorpej 148 1.21 apb /* 149 1.21 apb * For each type known to FSTYPE_DEFN (from <sys/disklabel.h>), 150 1.21 apb * a suitable case branch will convert the type number to a string. 151 1.21 apb */ 152 1.1 thorpej switch (fstype) { 153 1.21 apb #define FSTYPE_TO_STR_CASE(tag, number, name, fsck, mount) \ 154 1.22 apb case __CONCAT(FS_,tag): str = __CONCAT(DKW_PTYPE_,tag); break; 155 1.21 apb FSTYPE_DEFN(FSTYPE_TO_STR_CASE) 156 1.21 apb #undef FSTYPE_TO_STR_CASE 157 1.1 thorpej default: str = NULL; break; 158 1.1 thorpej } 159 1.1 thorpej 160 1.1 thorpej return (str); 161 1.1 thorpej } 162 1.1 thorpej 163 1.1 thorpej static void 164 1.1 thorpej swap_disklabel(struct disklabel *lp) 165 1.1 thorpej { 166 1.1 thorpej int i; 167 1.1 thorpej 168 1.1 thorpej #define SWAP16(x) lp->x = bswap16(lp->x) 169 1.1 thorpej #define SWAP32(x) lp->x = bswap32(lp->x) 170 1.1 thorpej 171 1.1 thorpej SWAP32(d_magic); 172 1.1 thorpej SWAP16(d_type); 173 1.1 thorpej SWAP16(d_subtype); 174 1.1 thorpej SWAP32(d_secsize); 175 1.1 thorpej SWAP32(d_nsectors); 176 1.1 thorpej SWAP32(d_ntracks); 177 1.1 thorpej SWAP32(d_ncylinders); 178 1.1 thorpej SWAP32(d_secpercyl); 179 1.1 thorpej SWAP32(d_secperunit); 180 1.1 thorpej SWAP16(d_sparespertrack); 181 1.1 thorpej SWAP16(d_sparespercyl); 182 1.1 thorpej SWAP32(d_acylinders); 183 1.1 thorpej SWAP16(d_rpm); 184 1.1 thorpej SWAP16(d_interleave); 185 1.1 thorpej SWAP16(d_trackskew); 186 1.1 thorpej SWAP16(d_cylskew); 187 1.1 thorpej SWAP32(d_headswitch); 188 1.1 thorpej SWAP32(d_trkseek); 189 1.1 thorpej SWAP32(d_flags); 190 1.1 thorpej 191 1.1 thorpej for (i = 0; i < NDDATA; i++) 192 1.1 thorpej SWAP32(d_drivedata[i]); 193 1.1 thorpej for (i = 0; i < NSPARE; i++) 194 1.1 thorpej SWAP32(d_spare[i]); 195 1.3 perry 196 1.1 thorpej SWAP32(d_magic2); 197 1.1 thorpej SWAP16(d_checksum); 198 1.1 thorpej SWAP16(d_npartitions); 199 1.1 thorpej SWAP32(d_bbsize); 200 1.1 thorpej SWAP32(d_sbsize); 201 1.1 thorpej 202 1.1 thorpej for (i = 0; i < lp->d_npartitions; i++) { 203 1.1 thorpej SWAP32(d_partitions[i].p_size); 204 1.1 thorpej SWAP32(d_partitions[i].p_offset); 205 1.1 thorpej SWAP32(d_partitions[i].p_fsize); 206 1.1 thorpej SWAP16(d_partitions[i].p_cpg); 207 1.1 thorpej } 208 1.1 thorpej 209 1.1 thorpej #undef SWAP16 210 1.1 thorpej #undef SWAP32 211 1.1 thorpej } 212 1.1 thorpej 213 1.14 dyoung /* 214 1.14 dyoung * Add wedges for a valid NetBSD disklabel. 215 1.14 dyoung */ 216 1.14 dyoung static void 217 1.14 dyoung addwedges(const mbr_args_t *a, const struct disklabel *lp) 218 1.14 dyoung { 219 1.14 dyoung int error, i; 220 1.14 dyoung 221 1.14 dyoung for (i = 0; i < lp->d_npartitions; i++) { 222 1.14 dyoung struct dkwedge_info dkw; 223 1.14 dyoung const struct partition *p; 224 1.14 dyoung const char *ptype; 225 1.14 dyoung 226 1.14 dyoung p = &lp->d_partitions[i]; 227 1.14 dyoung 228 1.14 dyoung if (p->p_fstype == FS_UNUSED) 229 1.14 dyoung continue; 230 1.24 maxv 231 1.24 maxv memset(&dkw, 0, sizeof(dkw)); 232 1.24 maxv 233 1.20 apb ptype = bsdlabel_fstype_to_str(p->p_fstype); 234 1.20 apb if (ptype == NULL) 235 1.20 apb snprintf(dkw.dkw_ptype, sizeof(dkw.dkw_ptype), 236 1.20 apb "unknown#%u", p->p_fstype); 237 1.20 apb else 238 1.20 apb strlcpy(dkw.dkw_ptype, ptype, sizeof(dkw.dkw_ptype)); 239 1.14 dyoung 240 1.20 apb strlcpy(dkw.dkw_parent, a->pdk->dk_name, 241 1.20 apb sizeof(dkw.dkw_parent)); 242 1.14 dyoung dkw.dkw_offset = p->p_offset; 243 1.14 dyoung dkw.dkw_size = p->p_size; 244 1.14 dyoung 245 1.14 dyoung /* 246 1.17 mlelstv * If the label defines a name, append the partition 247 1.17 mlelstv * letter and use it as the wedge name. 248 1.17 mlelstv * Otherwise use historical disk naming style 249 1.14 dyoung * wedge names. 250 1.14 dyoung */ 251 1.17 mlelstv if (lp->d_packname[0] && 252 1.17 mlelstv strcmp(lp->d_packname,"fictitious") != 0) { 253 1.17 mlelstv snprintf((char *)&dkw.dkw_wname, sizeof(dkw.dkw_wname), 254 1.17 mlelstv "%.*s/%c", (int)sizeof(dkw.dkw_wname)-3, 255 1.17 mlelstv lp->d_packname, 'a' + i); 256 1.17 mlelstv } else { 257 1.17 mlelstv snprintf((char *)&dkw.dkw_wname, sizeof(dkw.dkw_wname), 258 1.17 mlelstv "%s%c", a->pdk->dk_name, 'a' + i); 259 1.17 mlelstv } 260 1.14 dyoung 261 1.14 dyoung error = dkwedge_add(&dkw); 262 1.14 dyoung if (error == EEXIST) 263 1.14 dyoung aprint_error("%s: wedge named '%s' already " 264 1.14 dyoung "exists, manual intervention required\n", 265 1.14 dyoung a->pdk->dk_name, dkw.dkw_wname); 266 1.14 dyoung else if (error) 267 1.14 dyoung aprint_error("%s: error %d adding partition " 268 1.14 dyoung "%d type %d\n", a->pdk->dk_name, error, 269 1.14 dyoung i, p->p_fstype); 270 1.14 dyoung } 271 1.14 dyoung } 272 1.14 dyoung 273 1.1 thorpej static int 274 1.1 thorpej validate_label(mbr_args_t *a, daddr_t label_sector, size_t label_offset) 275 1.1 thorpej { 276 1.1 thorpej struct disklabel *lp; 277 1.12 christos void *lp_lim; 278 1.14 dyoung int error, swapped; 279 1.14 dyoung uint16_t npartitions; 280 1.1 thorpej 281 1.25 jdolecek error = dkwedge_read(a->pdk, a->vp, label_sector, a->bp->b_data, 282 1.25 jdolecek a->secsize); 283 1.1 thorpej if (error) { 284 1.1 thorpej aprint_error("%s: unable to read BSD disklabel @ %" PRId64 285 1.1 thorpej ", error = %d\n", a->pdk->dk_name, label_sector, error); 286 1.1 thorpej a->error = error; 287 1.1 thorpej return (SCAN_ERROR); 288 1.1 thorpej } 289 1.1 thorpej 290 1.1 thorpej /* 291 1.1 thorpej * We ignore label_offset; this seems to have not been used 292 1.1 thorpej * consistently in the old code, requiring us to do the search 293 1.1 thorpej * in the sector. 294 1.1 thorpej */ 295 1.25 jdolecek lp = a->bp->b_data; 296 1.25 jdolecek lp_lim = (char *)a->bp->b_data + a->secsize - DISKLABEL_MINSIZE; 297 1.12 christos for (;; lp = (void *)((char *)lp + sizeof(uint32_t))) { 298 1.12 christos if ((char *)lp > (char *)lp_lim) 299 1.1 thorpej return (SCAN_CONTINUE); 300 1.25 jdolecek label_offset = (size_t)((char *)lp - (char *)a->bp->b_data); 301 1.2 thorpej if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 302 1.14 dyoung if (lp->d_magic != bswap32(DISKMAGIC) || 303 1.14 dyoung lp->d_magic2 != bswap32(DISKMAGIC)) 304 1.1 thorpej continue; 305 1.14 dyoung /* Label is in the other byte order. */ 306 1.14 dyoung swapped = 1; 307 1.14 dyoung } else 308 1.14 dyoung swapped = 0; 309 1.14 dyoung 310 1.14 dyoung npartitions = (swapped) ? bswap16(lp->d_npartitions) 311 1.14 dyoung : lp->d_npartitions; 312 1.14 dyoung 313 1.14 dyoung /* Validate label length. */ 314 1.14 dyoung if ((char *)lp + DISKLABEL_SIZE(npartitions) > 315 1.25 jdolecek (char *)a->bp->b_data + a->secsize) { 316 1.14 dyoung aprint_error("%s: BSD disklabel @ " 317 1.14 dyoung "%" PRId64 "+%zd has bogus partition count (%u)\n", 318 1.14 dyoung a->pdk->dk_name, label_sector, label_offset, 319 1.14 dyoung npartitions); 320 1.14 dyoung continue; 321 1.1 thorpej } 322 1.1 thorpej 323 1.1 thorpej /* 324 1.14 dyoung * We have validated the partition count. Checksum it. 325 1.14 dyoung * Note that we purposefully checksum before swapping 326 1.14 dyoung * the byte order. 327 1.1 thorpej */ 328 1.14 dyoung if (dkcksum_sized(lp, npartitions) != 0) { 329 1.1 thorpej aprint_error("%s: BSD disklabel @ %" PRId64 330 1.1 thorpej "+%zd has bad checksum\n", a->pdk->dk_name, 331 1.1 thorpej label_sector, label_offset); 332 1.1 thorpej continue; 333 1.1 thorpej } 334 1.14 dyoung /* Put the disklabel in the right order. */ 335 1.14 dyoung if (swapped) 336 1.14 dyoung swap_disklabel(lp); 337 1.14 dyoung addwedges(a, lp); 338 1.1 thorpej return (SCAN_FOUND); 339 1.1 thorpej } 340 1.1 thorpej } 341 1.1 thorpej 342 1.1 thorpej static int 343 1.1 thorpej scan_mbr(mbr_args_t *a, int (*actn)(mbr_args_t *, struct mbr_partition *, 344 1.1 thorpej int, u_int)) 345 1.1 thorpej { 346 1.1 thorpej struct mbr_partition ptns[MBR_PART_COUNT]; 347 1.1 thorpej struct mbr_partition *dp; 348 1.1 thorpej struct mbr_sector *mbr; 349 1.1 thorpej u_int ext_base, this_ext, next_ext; 350 1.1 thorpej int i, rval; 351 1.1 thorpej #ifdef COMPAT_386BSD_MBRPART 352 1.1 thorpej int dp_386bsd = -1; 353 1.1 thorpej #endif 354 1.1 thorpej 355 1.1 thorpej ext_base = 0; 356 1.1 thorpej this_ext = 0; 357 1.1 thorpej for (;;) { 358 1.25 jdolecek a->error = dkwedge_read(a->pdk, a->vp, this_ext, a->bp->b_data, 359 1.23 mlelstv a->secsize); 360 1.1 thorpej if (a->error) { 361 1.1 thorpej aprint_error("%s: unable to read MBR @ %u, " 362 1.1 thorpej "error = %d\n", a->pdk->dk_name, this_ext, 363 1.1 thorpej a->error); 364 1.1 thorpej return (SCAN_ERROR); 365 1.1 thorpej } 366 1.1 thorpej 367 1.25 jdolecek mbr = a->bp->b_data; 368 1.1 thorpej if (mbr->mbr_magic != htole16(MBR_MAGIC)) 369 1.1 thorpej return (SCAN_CONTINUE); 370 1.1 thorpej 371 1.1 thorpej /* Copy data out of buffer so action can use the buffer. */ 372 1.1 thorpej memcpy(ptns, &mbr->mbr_parts, sizeof(ptns)); 373 1.1 thorpej 374 1.1 thorpej /* Looks for NetBSD partition. */ 375 1.1 thorpej next_ext = 0; 376 1.1 thorpej dp = ptns; 377 1.1 thorpej for (i = 0; i < MBR_PART_COUNT; i++, dp++) { 378 1.1 thorpej if (dp->mbrp_type == 0) 379 1.1 thorpej continue; 380 1.1 thorpej if (MBR_IS_EXTENDED(dp->mbrp_type)) { 381 1.1 thorpej next_ext = le32toh(dp->mbrp_start); 382 1.1 thorpej continue; 383 1.1 thorpej } 384 1.1 thorpej #ifdef COMPAT_386BSD_MBRPART 385 1.1 thorpej if (dp->mbrp_type == MBR_PTYPE_386BSD) { 386 1.1 thorpej /* 387 1.1 thorpej * If more than one matches, take last, 388 1.1 thorpej * as NetBSD install tool does. 389 1.1 thorpej */ 390 1.1 thorpej if (this_ext == 0) 391 1.1 thorpej dp_386bsd = i; 392 1.1 thorpej continue; 393 1.1 thorpej } 394 1.1 thorpej #endif 395 1.1 thorpej rval = (*actn)(a, dp, i, this_ext); 396 1.1 thorpej if (rval != SCAN_CONTINUE) 397 1.1 thorpej return (rval); 398 1.1 thorpej } 399 1.1 thorpej if (next_ext == 0) 400 1.1 thorpej break; 401 1.1 thorpej if (ext_base == 0) { 402 1.1 thorpej ext_base = next_ext; 403 1.1 thorpej next_ext = 0; 404 1.1 thorpej } 405 1.1 thorpej next_ext += ext_base; 406 1.1 thorpej if (next_ext <= this_ext) 407 1.1 thorpej break; 408 1.1 thorpej this_ext = next_ext; 409 1.1 thorpej } 410 1.1 thorpej #ifdef COMPAT_386BSD_MBRPART 411 1.1 thorpej if (this_ext == 0 && dp_386bsd != -1) 412 1.1 thorpej return ((*actn)(a, &ptns[dp_386bsd], dp_386bsd, 0)); 413 1.1 thorpej #endif 414 1.1 thorpej return (SCAN_CONTINUE); 415 1.1 thorpej } 416 1.1 thorpej 417 1.1 thorpej static int 418 1.9 christos look_netbsd_part(mbr_args_t *a, struct mbr_partition *dp, int slot, 419 1.8 christos u_int ext_base) 420 1.1 thorpej { 421 1.1 thorpej int ptn_base = ext_base + le32toh(dp->mbrp_start); 422 1.1 thorpej int rval; 423 1.1 thorpej 424 1.1 thorpej if ( 425 1.1 thorpej #ifdef COMPAT_386BSD_MBRPART 426 1.1 thorpej dp->mbrp_type == MBR_PTYPE_386BSD || 427 1.1 thorpej #endif 428 1.1 thorpej dp->mbrp_type == MBR_PTYPE_NETBSD) { 429 1.1 thorpej rval = validate_label(a, ptn_base + BSD44_MBR_LABELSECTOR, 0); 430 1.1 thorpej 431 1.1 thorpej /* If we got a NetBSD label, look no further. */ 432 1.1 thorpej if (rval == SCAN_FOUND) 433 1.1 thorpej return (rval); 434 1.1 thorpej } 435 1.1 thorpej 436 1.1 thorpej return (SCAN_CONTINUE); 437 1.1 thorpej } 438 1.11 martin 439 1.1 thorpej static int 440 1.1 thorpej dkwedge_discover_bsdlabel(struct disk *pdk, struct vnode *vp) 441 1.1 thorpej { 442 1.1 thorpej mbr_args_t a; 443 1.1 thorpej const struct disklabel_location *dl; 444 1.1 thorpej int rval; 445 1.1 thorpej 446 1.1 thorpej a.pdk = pdk; 447 1.23 mlelstv a.secsize = DEV_BSIZE << pdk->dk_blkshift; 448 1.1 thorpej a.vp = vp; 449 1.25 jdolecek a.bp = geteblk(a.secsize); 450 1.1 thorpej a.error = 0; 451 1.1 thorpej 452 1.1 thorpej /* MBR search. */ 453 1.1 thorpej rval = scan_mbr(&a, look_netbsd_part); 454 1.1 thorpej if (rval != SCAN_CONTINUE) { 455 1.1 thorpej if (rval == SCAN_FOUND) 456 1.1 thorpej a.error = 0; /* found it, wedges installed */ 457 1.1 thorpej goto out; 458 1.1 thorpej } 459 1.1 thorpej 460 1.1 thorpej /* Known location search. */ 461 1.1 thorpej for (dl = disklabel_locations; dl->label_sector != -1; dl++) { 462 1.1 thorpej rval = validate_label(&a, dl->label_sector, dl->label_offset); 463 1.1 thorpej if (rval != SCAN_CONTINUE) { 464 1.1 thorpej if (rval == SCAN_FOUND) 465 1.1 thorpej a.error = 0; /* found it, wedges installed */ 466 1.1 thorpej goto out; 467 1.1 thorpej } 468 1.1 thorpej } 469 1.1 thorpej 470 1.1 thorpej /* No NetBSD disklabel found. */ 471 1.1 thorpej a.error = ESRCH; 472 1.1 thorpej out: 473 1.25 jdolecek brelse(a.bp, 0); 474 1.1 thorpej return (a.error); 475 1.1 thorpej } 476 1.1 thorpej 477 1.11 martin #ifdef _KERNEL 478 1.1 thorpej DKWEDGE_DISCOVERY_METHOD_DECL(BSD44, 5, dkwedge_discover_bsdlabel); 479 1.11 martin #endif 480