1 /* $NetBSD: disksubr.c,v 1.72 2022/07/05 19:31:04 andvar Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 32 */ 33 34 /* 35 * Copyright (c) 1994 Christian E. Hopps 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by the University of 48 * California, Berkeley and its contributors. 49 * 4. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 66 */ 67 68 #include <sys/cdefs.h> 69 __KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.72 2022/07/05 19:31:04 andvar Exp $"); 70 71 #include <sys/param.h> 72 #include <sys/systm.h> 73 #include <sys/buf.h> 74 #include <sys/disklabel.h> 75 #include <sys/disk.h> 76 77 /* 78 * In /usr/src/sys/dev/scsipi/sd.c, routine sdstart() adjusts the 79 * block numbers, it changes from DEV_BSIZE units to physical units: 80 * blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); 81 * As long as media with sector sizes of 512 bytes are used, this 82 * doesn't matter (divide by 1), but for successful usage of media with 83 * greater sector sizes (e.g. 640MB MO-media with 2048 bytes/sector) 84 * we must multiply block numbers with (lp->d_secsize / DEV_BSIZE) 85 * to keep "unchanged" physical block numbers. 86 */ 87 #define SD_C_ADJUSTS_NR 88 89 /* 90 * bitmap id's 91 */ 92 #define RDBLOCK_BID 1 93 #define PARTBLOCK_BID 2 94 #define BADBLOCK_BID 3 95 #define FSBLOCK_BID 4 96 #define LSEGBLOCK_BID 5 97 98 struct rdbmap { 99 long firstblk; 100 long lastblk; 101 int bigtype; 102 struct { 103 short next; 104 short prev; 105 char shortid; 106 } big[0]; 107 struct { 108 char next; 109 char prev; 110 char shortid; 111 } tab[0]; 112 }; 113 114 #define baddr(bp) (void *)((bp)->b_data) 115 116 u_long rdbchksum(void *); 117 struct adostype getadostype(u_long); 118 struct rdbmap *getrdbmap(dev_t, void (*)(struct buf *), struct disklabel *, 119 struct cpu_disklabel *); 120 121 /* 122 * Attempt to read a disk label from a device 123 * using the indicated strategy routine. 124 * The label must be partly set up before this: 125 * secpercyl and anything required in the strategy routine 126 * (e.g., sector size) must be filled in before calling us. 127 * Returns null on success and an error string on failure. 128 */ 129 const char * 130 readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp) 131 { 132 struct adostype adt; 133 struct partition *pp = NULL; 134 struct partblock *pbp; 135 struct rdblock *rbp; 136 struct buf *bp; 137 const char *msg; 138 char *bcpls, *s, bcpli; 139 int cindex, i, nopname; 140 u_long nextb; 141 struct disklabel *dlp; 142 143 clp->rdblock = RDBNULL; 144 /* 145 * give some guaranteed validity to 146 * the disklabel 147 */ 148 if (lp->d_secperunit == 0) 149 lp->d_secperunit = 0x1fffffff; 150 if (lp->d_secpercyl == 0) 151 lp->d_secpercyl = 0x1fffffff; 152 lp->d_npartitions = RAW_PART + 1; 153 154 if (lp->d_partitions[RAW_PART].p_size == 0) 155 lp->d_partitions[RAW_PART].p_size = 0x1fffffff; 156 lp->d_partitions[RAW_PART].p_offset = 0; 157 /* if no 'a' partition, default it to copy of 'c' as BSDFFS */ 158 if (lp->d_partitions[0].p_size == 0) { 159 lp->d_partitions[0].p_size = lp->d_partitions[RAW_PART].p_size; 160 lp->d_partitions[0].p_offset = 0; 161 lp->d_partitions[0].p_fstype = FS_BSDFFS; 162 lp->d_partitions[0].p_fsize = 1024; 163 lp->d_partitions[0].p_frag = 8; 164 lp->d_partitions[0].p_cpg = 0; 165 } 166 167 /* obtain buffer to probe drive with */ 168 bp = geteblk((int)lp->d_secsize); 169 170 /* 171 * request no partition relocation by driver on I/O operations 172 */ 173 #ifdef _KERNEL 174 bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART); 175 #else 176 bp->b_dev = dev; 177 #endif 178 msg = NULL; 179 180 /* 181 * find the RDB block 182 * XXX Need to check for a standard label if this fails (fd0 etc..) 183 */ 184 for (nextb = 0; nextb < RDB_MAXBLOCKS; nextb++) { 185 bp->b_blkno = nextb; 186 bp->b_cylinder = bp->b_blkno / lp->d_secpercyl; 187 bp->b_bcount = lp->d_secsize; 188 bp->b_oflags &= ~(BO_DONE); 189 bp->b_flags |= B_READ; 190 #ifdef SD_C_ADJUSTS_NR 191 bp->b_blkno *= (lp->d_secsize / DEV_BSIZE); 192 #endif 193 strat(bp); 194 195 if (biowait(bp)) { 196 msg = "rdb scan I/O error"; 197 goto done; 198 } 199 rbp = baddr(bp); 200 if (rbp->id == RDBLOCK_ID) { 201 if (rdbchksum(rbp) == 0) 202 break; 203 else 204 msg = "rdb bad checksum"; 205 } 206 /* Check for native NetBSD label? */ 207 dlp = (struct disklabel *)((char*)bp->b_data + LABELOFFSET); 208 if (dlp->d_magic == DISKMAGIC) { 209 if (dkcksum(dlp)) 210 msg = "NetBSD disk label corrupted"; 211 else { 212 /* remember block and continue searching? */ 213 *lp = *dlp; 214 brelse(bp, 0); 215 return(msg); 216 } 217 } 218 } 219 if (nextb == RDB_MAXBLOCKS) { 220 if (msg == NULL) 221 msg = "no rdb found"; 222 goto done; 223 } else if (msg) { 224 /* 225 * maybe we found an invalid one before a valid. 226 * clear err. 227 */ 228 msg = NULL; 229 } 230 clp->rdblock = nextb; 231 232 /* RDB present, clear disklabel partition table before doing PART blks */ 233 for (i = 0; i < MAXPARTITIONS; i++) { 234 clp->pbindex[i] = -1; 235 clp->pblist[i] = RDBNULL; 236 if (i == RAW_PART) 237 continue; 238 lp->d_partitions[i].p_size = 0; 239 lp->d_partitions[i].p_offset = 0; 240 } 241 242 if (lp->d_secsize != rbp->nbytes) { 243 lp->d_secsize = rbp->nbytes; 244 allocbuf(bp, (int)lp->d_secsize, 1); 245 rbp = baddr(bp); 246 } 247 lp->d_nsectors = rbp->nsectors; 248 lp->d_ntracks = rbp->nheads; 249 /* 250 * should be rdb->ncylinders however this is a bogus value 251 * sometimes it seems 252 */ 253 if (rbp->highcyl == 0) 254 lp->d_ncylinders = rbp->ncylinders; 255 else 256 lp->d_ncylinders = rbp->highcyl + 1; 257 /* 258 * I also don't trust rdb->secpercyl 259 */ 260 lp->d_secpercyl = uimin(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks); 261 if (lp->d_secpercyl == 0) 262 lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; 263 #ifdef DIAGNOSTIC 264 if (lp->d_ncylinders != rbp->ncylinders) 265 printf("warning found rdb->ncylinders(%" PRIu32 ") != " 266 "rdb->highcyl(%" PRIu32 ") + 1\n", rbp->ncylinders, 267 rbp->highcyl); 268 if (lp->d_nsectors * lp->d_ntracks != rbp->secpercyl) 269 printf("warning found rdb->secpercyl(%" PRIu32 ") != " 270 "rdb->nsectors(%" PRIu32 ") * rdb->nheads(%" PRIu32 ")\n", 271 rbp->secpercyl, rbp->nsectors, rbp->nheads); 272 #endif 273 lp->d_sparespercyl = 274 uimax(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks) 275 - lp->d_secpercyl; 276 if (lp->d_sparespercyl == 0) 277 lp->d_sparespertrack = 0; 278 else { 279 lp->d_sparespertrack = lp->d_sparespercyl / lp->d_ntracks; 280 #ifdef DIAGNOSTIC 281 if (lp->d_sparespercyl % lp->d_ntracks) 282 printf("warning lp->d_sparespercyl(%d) not multiple " 283 "of lp->d_ntracks(%d)\n", lp->d_sparespercyl, 284 lp->d_ntracks); 285 #endif 286 } 287 288 lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders; 289 lp->d_acylinders = rbp->ncylinders - (rbp->highcyl - rbp->lowcyl + 1); 290 lp->d_rpm = 3600; /* good guess I suppose. */ 291 lp->d_interleave = rbp->interleave; 292 lp->d_headswitch = lp->d_flags = lp->d_trackskew = lp->d_cylskew = 0; 293 lp->d_trkseek = /* rbp->steprate */ 0; 294 295 /* 296 * raw partition gets the entire disk 297 */ 298 lp->d_partitions[RAW_PART].p_size = rbp->ncylinders * lp->d_secpercyl; 299 300 /* 301 * scan for partition blocks 302 */ 303 nopname = 1; 304 cindex = 0; 305 for (nextb = rbp->partbhead; nextb != RDBNULL; nextb = pbp->next) { 306 bp->b_blkno = nextb; 307 bp->b_cylinder = bp->b_blkno / lp->d_secpercyl; 308 bp->b_bcount = lp->d_secsize; 309 bp->b_oflags &= ~(BO_DONE); 310 bp->b_flags |= B_READ; 311 #ifdef SD_C_ADJUSTS_NR 312 bp->b_blkno *= (lp->d_secsize / DEV_BSIZE); 313 #endif 314 strat(bp); 315 316 if (biowait(bp)) { 317 msg = "partition scan I/O error"; 318 goto done; 319 } 320 pbp = baddr(bp); 321 322 if (pbp->id != PARTBLOCK_ID) { 323 msg = "partition block with bad id"; 324 goto done; 325 } 326 if (rdbchksum(pbp)) { 327 msg = "partition block bad checksum"; 328 goto done; 329 } 330 331 if (pbp->e.tabsize < 11) { 332 /* 333 * not enough info, too funky for us. 334 * I don't want to skip I want it fixed. 335 */ 336 msg = "bad partition info (environ < 11)"; 337 goto done; 338 } 339 340 /* 341 * XXXX should be ">" however some vendors don't know 342 * what a table size is so, we hack for them. 343 * the other checks can fail for all I care but this 344 * is a very common value. *sigh*. 345 */ 346 if (pbp->e.tabsize >= 16) 347 adt = getadostype(pbp->e.dostype); 348 else { 349 adt.archtype = ADT_UNKNOWN; 350 adt.fstype = FS_UNUSED; 351 } 352 353 switch (adt.archtype) { 354 case ADT_NETBSDROOT: 355 pp = &lp->d_partitions[0]; 356 if (pp->p_size) { 357 printf("WARN: more than one root, ignoring\n"); 358 clp->rdblock = RDBNULL; /* invalidate cpulab */ 359 continue; 360 } 361 break; 362 case ADT_NETBSDSWAP: 363 pp = &lp->d_partitions[1]; 364 if (pp->p_size) { 365 printf("WARN: more than one swap, ignoring\n"); 366 clp->rdblock = RDBNULL; /* invalidate cpulab */ 367 continue; 368 } 369 break; 370 case ADT_NETBSDUSER: 371 case ADT_AMIGADOS: 372 case ADT_AMIX: 373 case ADT_EXT2: 374 case ADT_RAID: 375 case ADT_UNKNOWN: 376 pp = &lp->d_partitions[lp->d_npartitions]; 377 break; 378 } 379 if (lp->d_npartitions <= (pp - lp->d_partitions)) 380 lp->d_npartitions = (pp - lp->d_partitions) + 1; 381 382 #ifdef DIAGNOSTIC 383 if (lp->d_secpercyl * lp->d_secsize != 384 (pbp->e.secpertrk * pbp->e.numheads * pbp->e.sizeblock<<2)) { 385 if (pbp->partname[0] + 1 < sizeof(pbp->partname)) 386 pbp->partname[pbp->partname[0] + 1] = 0; 387 else 388 pbp->partname[sizeof(pbp->partname) - 1] = 0; 389 printf("Partition '%s' geometry %" PRIu32 "/%" PRIu32 390 " differs", 391 pbp->partname + 1, pbp->e.numheads, 392 pbp->e.secpertrk); 393 printf(" from RDB %d/%d=%d\n", lp->d_ntracks, 394 lp->d_nsectors, lp->d_secpercyl); 395 } 396 #endif 397 /* 398 * insert sort in increasing offset order 399 */ 400 while ((pp - lp->d_partitions) > RAW_PART + 1) { 401 daddr_t boff; 402 403 boff = pbp->e.lowcyl * pbp->e.secpertrk 404 * pbp->e.numheads 405 * ((pbp->e.sizeblock << 2) / lp->d_secsize); 406 if (boff > (pp - 1)->p_offset) 407 break; 408 *pp = *(pp - 1); /* struct copy */ 409 pp--; 410 } 411 i = (pp - lp->d_partitions); 412 if (nopname || i == 1) { 413 /* 414 * either we have no packname yet or we found 415 * the swap partition. copy BCPL string into packname 416 * [the reason we use the swap partition: the user 417 * can supply a decent packname without worry 418 * of having to access an oddly named partition 419 * under AmigaDos] 420 */ 421 s = lp->d_packname; 422 bcpls = &pbp->partname[1]; 423 bcpli = pbp->partname[0]; 424 if (sizeof(lp->d_packname) <= bcpli) 425 bcpli = sizeof(lp->d_packname) - 1; 426 while (bcpli--) 427 *s++ = *bcpls++; 428 *s = 0; 429 nopname = 0; 430 } 431 432 pp->p_size = (pbp->e.highcyl - pbp->e.lowcyl + 1) 433 * pbp->e.secpertrk * pbp->e.numheads 434 * ((pbp->e.sizeblock << 2) / lp->d_secsize); 435 pp->p_offset = pbp->e.lowcyl * pbp->e.secpertrk 436 * pbp->e.numheads 437 * ((pbp->e.sizeblock << 2) / lp->d_secsize); 438 pp->p_fstype = adt.fstype; 439 if (adt.archtype == ADT_AMIGADOS) { 440 /* 441 * Save reserved blocks at begin in cpg and 442 * adjust size by reserved blocks at end 443 */ 444 int bsize, secperblk, minbsize, prefac; 445 446 minbsize = uimax(512, lp->d_secsize); 447 448 bsize = pbp->e.sizeblock << 2; 449 secperblk = pbp->e.secperblk; 450 prefac = pbp->e.prefac; 451 452 while (bsize > minbsize) { 453 bsize >>= 1; 454 secperblk <<= 1; 455 prefac <<= 1; 456 } 457 458 if (bsize == minbsize) { 459 pp->p_fsize = bsize; 460 pp->p_frag = secperblk; 461 pp->p_cpg = pbp->e.resvblocks; 462 pp->p_size -= prefac; 463 } else { 464 adt.archtype = ADT_UNKNOWN; 465 adt.fstype = FS_UNUSED; 466 } 467 } else if (pbp->e.tabsize >= 22 && ISFSARCH_NETBSD(adt)) { 468 pp->p_fsize = pbp->e.fsize; 469 pp->p_frag = pbp->e.frag; 470 pp->p_cpg = pbp->e.cpg; 471 } else if (adt.fstype == FS_ISO9660) { 472 pp->p_fsize = 0; 473 pp->p_frag = 0; 474 pp->p_cpg = 0; 475 } else { 476 pp->p_fsize = 1024; 477 pp->p_frag = 8; 478 pp->p_cpg = 0; 479 } 480 481 /* 482 * store this partitions block number 483 */ 484 clp->pblist[clp->pbindex[i] = cindex++] = nextb; 485 } 486 /* 487 * calulate new checksum. 488 */ 489 lp->d_magic = lp->d_magic2 = DISKMAGIC; 490 lp->d_checksum = 0; 491 lp->d_checksum = dkcksum(lp); 492 if (clp->rdblock != RDBNULL) 493 clp->valid = 1; 494 done: 495 if (clp->valid == 0) 496 clp->rdblock = RDBNULL; 497 brelse(bp, 0); 498 return(msg); 499 } 500 501 /* 502 * Write disk label back to device after modification. 503 * this means write out the Rigid disk blocks to represent the 504 * label. Hope the user was carefull. 505 */ 506 int 507 writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp) 508 { 509 struct buf *bp; 510 struct disklabel *dlp; 511 int error = 0; 512 513 /* If RDB was present, we don't support writing them yet. */ 514 if (clp->rdblock != RDBNULL) 515 return(EINVAL); 516 517 /* RDB was not present, write out native NetBSD label */ 518 bp = geteblk((int)lp->d_secsize); 519 bp->b_dev = dev; 520 bp->b_blkno = LABELSECTOR; 521 bp->b_cylinder = 0; 522 bp->b_bcount = lp->d_secsize; 523 bp->b_flags |= B_READ; /* get current label */ 524 (*strat)(bp); 525 if ((error = biowait(bp)) != 0) 526 goto done; 527 528 dlp = (struct disklabel *)((char*)bp->b_data + LABELOFFSET); 529 *dlp = *lp; /* struct assignment */ 530 531 bp->b_oflags &= ~(BO_DONE); 532 bp->b_flags &= ~(B_READ); 533 bp->b_flags |= B_WRITE; 534 (*strat)(bp); 535 error = biowait(bp); 536 537 done: 538 brelse(bp, 0); 539 return (error); 540 } 541 542 u_long 543 rdbchksum(void *bdata) 544 { 545 u_long *blp, cnt, val; 546 547 blp = bdata; 548 cnt = blp[1]; 549 val = 0; 550 551 while (cnt--) 552 val += *blp++; 553 return(val); 554 } 555 556 struct adostype 557 getadostype(u_long dostype) 558 { 559 struct adostype adt; 560 u_long t3, b1; 561 562 t3 = dostype & 0xffffff00; 563 b1 = dostype & 0x000000ff; 564 565 adt.fstype = b1; 566 567 switch (t3) { 568 case DOST_NBR: 569 adt.archtype = ADT_NETBSDROOT; 570 return(adt); 571 case DOST_NBS: 572 adt.archtype = ADT_NETBSDSWAP; 573 return(adt); 574 case DOST_NBU: 575 adt.archtype = ADT_NETBSDUSER; 576 return(adt); 577 case DOST_MUFS: 578 /* check for 'muFS'? */ 579 adt.archtype = ADT_AMIGADOS; 580 adt.fstype = FS_ADOS; 581 return(adt); 582 case DOST_DOS: 583 adt.archtype = ADT_AMIGADOS; 584 if (b1 > 5) 585 adt.fstype = FS_UNUSED; 586 else 587 adt.fstype = FS_ADOS; 588 return(adt); 589 590 case DOST_AMIX: 591 adt.archtype = ADT_AMIX; 592 if (b1 == 2) 593 adt.fstype = FS_BSDFFS; 594 else 595 adt.fstype = FS_UNUSED; 596 return(adt); 597 case DOST_XXXBSD: 598 #ifdef DIAGNOSTIC 599 printf("found dostype: 0x%lx which is deprecated", dostype); 600 #endif 601 if (b1 == 'S') { 602 dostype = DOST_NBS; 603 dostype |= FS_SWAP; 604 } else { 605 if (b1 == 'R') 606 dostype = DOST_NBR; 607 else 608 dostype = DOST_NBU; 609 dostype |= FS_BSDFFS; 610 } 611 #ifdef DIAGNOSTIC 612 printf(" using: 0x%lx instead\n", dostype); 613 #endif 614 return(getadostype(dostype)); 615 616 case DOST_EXT2: 617 adt.archtype = ADT_EXT2; 618 adt.fstype = FS_EX2FS; 619 return(adt); 620 621 case DOST_RAID: 622 adt.archtype = ADT_RAID; 623 adt.fstype = FS_RAID; 624 return(adt); 625 626 default: 627 #ifdef DIAGNOSTIC 628 printf("warning unknown dostype: 0x%lx marking unused\n", 629 dostype); 630 #endif 631 adt.archtype = ADT_UNKNOWN; 632 adt.fstype = FS_UNUSED; 633 return(adt); 634 } 635 } 636 637 /* 638 * if we find a bad block we kill it (and the chain it belongs to for 639 * lseg or end the chain for part, badb, fshd) 640 */ 641 struct rdbmap * 642 getrdbmap(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp) 643 { 644 struct buf *bp; 645 646 bp = (void *)geteblk(lp->d_secsize); 647 /* 648 * get the raw partition 649 */ 650 651 bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART); 652 /* XXX finish */ 653 brelse(bp, 0); 654 return(NULL); 655 } 656 657