1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 1994 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ 28*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ 29*0Sstevel@tonic-gate /* All Rights Reserved */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate /* 32*0Sstevel@tonic-gate * Copyrighted as an unpublished work. 33*0Sstevel@tonic-gate * (c) Copyright INTERACTIVE Systems Corporation 1986, 1988, 1990 34*0Sstevel@tonic-gate * All rights reserved. 35*0Sstevel@tonic-gate */ 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate #include <sys/types.h> 40*0Sstevel@tonic-gate #include <ctype.h> 41*0Sstevel@tonic-gate #include <fcntl.h> 42*0Sstevel@tonic-gate #include <malloc.h> 43*0Sstevel@tonic-gate #include <sys/stat.h> 44*0Sstevel@tonic-gate #include <sys/swap.h> 45*0Sstevel@tonic-gate #include <stdio.h> 46*0Sstevel@tonic-gate #include <string.h> 47*0Sstevel@tonic-gate #include <sys/vtoc.h> 48*0Sstevel@tonic-gate #include <sys/param.h> 49*0Sstevel@tonic-gate #include <sys/dkio.h> 50*0Sstevel@tonic-gate #include <sys/dktp/altsctr.h> 51*0Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 52*0Sstevel@tonic-gate #include "badsec.h" 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate #define FAILURE 0 55*0Sstevel@tonic-gate #define SUCCESS 1 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate #define CMD_READ 0 58*0Sstevel@tonic-gate #define CMD_WRITE 1 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate struct badsec_lst *badsl_chain; 61*0Sstevel@tonic-gate int badsl_chain_cnt; 62*0Sstevel@tonic-gate struct badsec_lst *gbadsl_chain; 63*0Sstevel@tonic-gate int gbadsl_chain_cnt; 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate extern struct dk_geom dkg; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate extern int alts_fd; 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate struct alts_mempart alts_part = { 0, NULL, 0 }; 70*0Sstevel@tonic-gate struct alts_mempart *ap = &alts_part; /* pointer to incore alts tables */ 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate /* 73*0Sstevel@tonic-gate * updatebadsec () -- update bad sector/track mapping tables 74*0Sstevel@tonic-gate */ 75*0Sstevel@tonic-gate updatebadsec(part, init_flag) 76*0Sstevel@tonic-gate int init_flag; 77*0Sstevel@tonic-gate struct partition *part; 78*0Sstevel@tonic-gate { 79*0Sstevel@tonic-gate if (init_flag) 80*0Sstevel@tonic-gate ap->ap_flag |= ALTS_ADDPART; 81*0Sstevel@tonic-gate get_badsec(); 82*0Sstevel@tonic-gate read_altsctr(part, 1); 83*0Sstevel@tonic-gate ent_sort(ap->ap_gbadp, ap->ap_gbadcnt); 84*0Sstevel@tonic-gate ent_compress(ap->ap_gbadp, ap->ap_gbadcnt); 85*0Sstevel@tonic-gate gen_alts_ent(); 86*0Sstevel@tonic-gate compress_map(); 87*0Sstevel@tonic-gate return(SUCCESS); 88*0Sstevel@tonic-gate } 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate /* 91*0Sstevel@tonic-gate * read_altsctr( ptr to alternate sector partition ) 92*0Sstevel@tonic-gate * -- read the alternate sector partition tables 93*0Sstevel@tonic-gate */ 94*0Sstevel@tonic-gate read_altsctr(part, badok) 95*0Sstevel@tonic-gate struct partition *part; 96*0Sstevel@tonic-gate int badok; 97*0Sstevel@tonic-gate { 98*0Sstevel@tonic-gate int ret; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate if (ap->ap_tblp == NULL) { 101*0Sstevel@tonic-gate /* allocate buffer for the alts partition table (sector size) */ 102*0Sstevel@tonic-gate ap->ap_tbl_secsiz = byte_to_secsiz(ALTS_PARTTBL_SIZE,NBPSCTR); 103*0Sstevel@tonic-gate ap->ap_tblp = (struct alts_parttbl *)malloc(ap->ap_tbl_secsiz); 104*0Sstevel@tonic-gate if (ap->ap_tblp == NULL) { 105*0Sstevel@tonic-gate fprintf(stderr, "Unable to malloc alternate partition table.\n"); 106*0Sstevel@tonic-gate exit(50); 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate /* allocate buffer for the alts partition map (sector size) */ 110*0Sstevel@tonic-gate /* buffers include the disk image bit map */ 111*0Sstevel@tonic-gate /* and the incore transformed char map */ 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate if ((ap->ap_memmapp = (unchar *)malloc(part->p_size)) == NULL) { 114*0Sstevel@tonic-gate fprintf(stderr, "Unable to malloc incore alternate partition map.\n"); 115*0Sstevel@tonic-gate exit(51); 116*0Sstevel@tonic-gate } 117*0Sstevel@tonic-gate ap->ap_tblp->alts_map_len = (part->p_size + 8 - 1) / 8; 118*0Sstevel@tonic-gate ap->ap_map_secsiz=byte_to_secsiz(ap->ap_tblp->alts_map_len,NBPSCTR); 119*0Sstevel@tonic-gate ap->ap_map_sectot = ap->ap_map_secsiz / NBPSCTR; 120*0Sstevel@tonic-gate if ((ap->ap_mapp = (unchar *)malloc(ap->ap_map_secsiz)) == NULL) { 121*0Sstevel@tonic-gate fprintf(stderr, "Unable to malloc alternate partition map.\n"); 122*0Sstevel@tonic-gate exit(52); 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate /* clear the buffers to zero */ 125*0Sstevel@tonic-gate memset(ap->ap_memmapp,0,part->p_size); 126*0Sstevel@tonic-gate memset(ap->ap_mapp,0,ap->ap_map_secsiz); 127*0Sstevel@tonic-gate ap->part = *part; /* struct copy */ 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate /* 130*0Sstevel@tonic-gate * if add alternate partition flag is set, then install the partition 131*0Sstevel@tonic-gate * otherwise read the alts partition info from disk 132*0Sstevel@tonic-gate * if failed, then assume the first installation 133*0Sstevel@tonic-gate */ 134*0Sstevel@tonic-gate if (ap->ap_flag & ALTS_ADDPART) 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate fprintf(stderr, "WARNING: Manually initializing alternate table.\n"); 137*0Sstevel@tonic-gate init_altsctr(); 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate else { 140*0Sstevel@tonic-gate if (get_altsctr(badok) == SUCCESS) 141*0Sstevel@tonic-gate chk_badsec(); 142*0Sstevel@tonic-gate else 143*0Sstevel@tonic-gate init_altsctr(); 144*0Sstevel@tonic-gate } 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate } 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate /* 150*0Sstevel@tonic-gate * checking duplicate bad sectors or bad sectors in ALTSCTR partition 151*0Sstevel@tonic-gate */ 152*0Sstevel@tonic-gate chk_badsec() 153*0Sstevel@tonic-gate { 154*0Sstevel@tonic-gate daddr_t badsec; 155*0Sstevel@tonic-gate daddr_t altsp_srtsec = ap->part.p_start; 156*0Sstevel@tonic-gate daddr_t altsp_endsec = ap->part.p_start + ap->part.p_size - 1; 157*0Sstevel@tonic-gate int cnt; 158*0Sstevel@tonic-gate int status; 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate for (cnt=0; cnt < ap->ap_gbadcnt; cnt++) { 161*0Sstevel@tonic-gate badsec = (ap->ap_gbadp)[cnt].bad_start; 162*0Sstevel@tonic-gate /* if bad sector is within the ATLSCTR partition */ 163*0Sstevel@tonic-gate if ((badsec >= altsp_srtsec) && (badsec <= altsp_endsec)) { 164*0Sstevel@tonic-gate if ((ap->ap_memmapp)[badsec - altsp_srtsec] != ALTS_BAD) { 165*0Sstevel@tonic-gate if ((badsec >= altsp_srtsec) && (badsec <= (altsp_srtsec + 166*0Sstevel@tonic-gate ap->ap_tbl_secsiz / NBPSCTR - 1))) { 167*0Sstevel@tonic-gate fprintf(stderr, "Alternate partition information table is bad.\n"); 168*0Sstevel@tonic-gate exit(53); 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate if ((badsec >= altsp_srtsec+ap->ap_tblp->alts_map_base) && 171*0Sstevel@tonic-gate (badsec <= (altsp_srtsec + ap->ap_tblp->alts_map_base + 172*0Sstevel@tonic-gate ap->ap_map_sectot - 1))) { 173*0Sstevel@tonic-gate fprintf(stderr, "Alternate partition map is bad.\n"); 174*0Sstevel@tonic-gate exit(54); 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate if ((badsec >= altsp_srtsec+ap->ap_tblp->alts_ent_base) && 177*0Sstevel@tonic-gate (badsec <= (altsp_srtsec + ap->ap_tblp->alts_ent_base + 178*0Sstevel@tonic-gate ap->ap_ent_secsiz / NBPSCTR - 1))) { 179*0Sstevel@tonic-gate fprintf(stderr, "Alternate partition entry table is bad.\n"); 180*0Sstevel@tonic-gate exit(55); 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate (ap->ap_memmapp)[badsec - altsp_srtsec] = ALTS_BAD; 183*0Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 184*0Sstevel@tonic-gate } else { 185*0Sstevel@tonic-gate status = chk_bad_altsctr(badsec); 186*0Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 187*0Sstevel@tonic-gate } 188*0Sstevel@tonic-gate } else { 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * binary search for bad sector in the alts entry table 191*0Sstevel@tonic-gate */ 192*0Sstevel@tonic-gate status = ent_bsearch(ap->ap_entp, ap->ap_tblp->alts_ent_used, 193*0Sstevel@tonic-gate &((ap->ap_gbadp)[cnt]) ); 194*0Sstevel@tonic-gate /* 195*0Sstevel@tonic-gate * if the bad sector had already been remapped(found in alts_entry) 196*0Sstevel@tonic-gate * then ignore the bad sector 197*0Sstevel@tonic-gate */ 198*0Sstevel@tonic-gate if (status != -1) { 199*0Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate /* 210*0Sstevel@tonic-gate * initialize the alternate partition tables 211*0Sstevel@tonic-gate */ 212*0Sstevel@tonic-gate init_altsctr() 213*0Sstevel@tonic-gate { 214*0Sstevel@tonic-gate daddr_t badsec; 215*0Sstevel@tonic-gate daddr_t altsp_srtsec = ap->part.p_start; 216*0Sstevel@tonic-gate daddr_t altsp_endsec = ap->part.p_start + ap->part.p_size - 1; 217*0Sstevel@tonic-gate int cnt; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate ap->ap_entp = NULL; 220*0Sstevel@tonic-gate ap->ap_ent_secsiz = 0; 221*0Sstevel@tonic-gate ap->ap_tblp->alts_sanity = ALTS_SANITY; 222*0Sstevel@tonic-gate ap->ap_tblp->alts_version= ALTS_VERSION1; 223*0Sstevel@tonic-gate ap->ap_tblp->alts_map_len = (ap->part.p_size + 8 - 1) / 8; 224*0Sstevel@tonic-gate ap->ap_tblp->alts_ent_used = 0; 225*0Sstevel@tonic-gate ap->ap_tblp->alts_ent_base = 0; 226*0Sstevel@tonic-gate ap->ap_tblp->alts_ent_end = 0; 227*0Sstevel@tonic-gate ap->ap_tblp->alts_resv_base = ap->part.p_size - 1; 228*0Sstevel@tonic-gate for (cnt=0; cnt<5; cnt++) 229*0Sstevel@tonic-gate ap->ap_tblp->alts_pad[cnt]=0; 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate for (cnt=0; cnt < ap->ap_gbadcnt; cnt++) { 232*0Sstevel@tonic-gate badsec = (ap->ap_gbadp)[cnt].bad_start; 233*0Sstevel@tonic-gate if ((badsec >= altsp_srtsec) && (badsec <= altsp_endsec)) { 234*0Sstevel@tonic-gate if (badsec == altsp_srtsec) { 235*0Sstevel@tonic-gate fprintf(stderr, "First sector of alternate partition is bad.\n"); 236*0Sstevel@tonic-gate exit(56); 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate (ap->ap_memmapp)[badsec - altsp_srtsec] = ALTS_BAD; 239*0Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate /* allocate the alts_map on disk skipping possible bad sectors */ 244*0Sstevel@tonic-gate ap->ap_tblp->alts_map_base = 245*0Sstevel@tonic-gate altsmap_alloc(ap->ap_tbl_secsiz / NBPSCTR, 246*0Sstevel@tonic-gate ap->part.p_size, ap->ap_map_sectot, ALTS_MAP_UP); 247*0Sstevel@tonic-gate if (ap->ap_tblp->alts_map_base == NULL) { 248*0Sstevel@tonic-gate perror("Unable to allocate alternate map on disk: "); 249*0Sstevel@tonic-gate exit(57); 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate /* 256*0Sstevel@tonic-gate * read the alternate partition tables from disk 257*0Sstevel@tonic-gate */ 258*0Sstevel@tonic-gate int 259*0Sstevel@tonic-gate get_altsctr(badok) 260*0Sstevel@tonic-gate int badok; 261*0Sstevel@tonic-gate { 262*0Sstevel@tonic-gate /* get alts partition table info */ 263*0Sstevel@tonic-gate if (absdsk_io(alts_fd, 0, (char *)ap->ap_tblp, 264*0Sstevel@tonic-gate ap->ap_tbl_secsiz,CMD_READ)==FAILURE) { 265*0Sstevel@tonic-gate if (badok) 266*0Sstevel@tonic-gate return(FAILURE); 267*0Sstevel@tonic-gate perror("Unable to read alternate sector partition: "); 268*0Sstevel@tonic-gate exit(58); 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate if (ap->ap_tblp->alts_sanity != ALTS_SANITY) { 271*0Sstevel@tonic-gate if (badok) 272*0Sstevel@tonic-gate return(FAILURE); 273*0Sstevel@tonic-gate fprintf(stderr, "Bad alternate sector magic number.\n"); 274*0Sstevel@tonic-gate exit(69); 275*0Sstevel@tonic-gate } 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate /* get the alts map */ 278*0Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_map_base, 279*0Sstevel@tonic-gate (char *)ap->ap_mapp, ap->ap_map_secsiz, CMD_READ) == FAILURE) { 280*0Sstevel@tonic-gate if (badok) 281*0Sstevel@tonic-gate return(FAILURE); 282*0Sstevel@tonic-gate perror("Unable to read alternate sector partition map: "); 283*0Sstevel@tonic-gate exit(59); 284*0Sstevel@tonic-gate } 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate /* transform the disk image bit-map to incore char map */ 287*0Sstevel@tonic-gate expand_map(); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_used == 0) { 290*0Sstevel@tonic-gate ap->ap_entp = NULL; 291*0Sstevel@tonic-gate ap->ap_ent_secsiz = 0; 292*0Sstevel@tonic-gate } else { 293*0Sstevel@tonic-gate ap->ap_ent_secsiz = byte_to_secsiz( 294*0Sstevel@tonic-gate (ap->ap_tblp->alts_ent_used*ALTS_ENT_SIZE),NBPSCTR); 295*0Sstevel@tonic-gate if ((ap->ap_entp = (struct alts_ent *)malloc(ap->ap_ent_secsiz)) == NULL) { 296*0Sstevel@tonic-gate if (badok) 297*0Sstevel@tonic-gate return(FAILURE); 298*0Sstevel@tonic-gate fprintf(stderr, "Unable to malloc alternate sector entry table.\n"); 299*0Sstevel@tonic-gate exit(60); 300*0Sstevel@tonic-gate } 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_ent_base, 303*0Sstevel@tonic-gate (char *)ap->ap_entp, ap->ap_ent_secsiz, 304*0Sstevel@tonic-gate CMD_READ) ==FAILURE){ 305*0Sstevel@tonic-gate if (badok) 306*0Sstevel@tonic-gate return(FAILURE); 307*0Sstevel@tonic-gate perror("Unable to read alternate sector entry table: "); 308*0Sstevel@tonic-gate exit(61); 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate } 311*0Sstevel@tonic-gate return(SUCCESS); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate /* 316*0Sstevel@tonic-gate * update the new alternate partition tables on disk 317*0Sstevel@tonic-gate */ 318*0Sstevel@tonic-gate wr_altsctr() 319*0Sstevel@tonic-gate { 320*0Sstevel@tonic-gate int mystatus = FAILURE; 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate if (ap->ap_tblp == NULL) 323*0Sstevel@tonic-gate return; 324*0Sstevel@tonic-gate if (absdsk_io(alts_fd, 0, ap->ap_tblp, 325*0Sstevel@tonic-gate ap->ap_tbl_secsiz, CMD_WRITE) == FAILURE) { 326*0Sstevel@tonic-gate perror("Unable to write alternate sector partition: "); 327*0Sstevel@tonic-gate exit(62); 328*0Sstevel@tonic-gate } 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_map_base, 331*0Sstevel@tonic-gate ap->ap_mapp, ap->ap_map_secsiz, CMD_WRITE) == FAILURE){ 332*0Sstevel@tonic-gate perror("Unable to write alternate sector partition map: "); 333*0Sstevel@tonic-gate exit(63); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_used != 0) { 337*0Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_ent_base, 338*0Sstevel@tonic-gate (char *)ap->ap_entp, ap->ap_ent_secsiz, 339*0Sstevel@tonic-gate CMD_WRITE) == FAILURE) { 340*0Sstevel@tonic-gate perror("Unable to write alternate sector entry table: "); 341*0Sstevel@tonic-gate exit(64); 342*0Sstevel@tonic-gate } 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate } 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate /* 351*0Sstevel@tonic-gate * get a list of bad sector 352*0Sstevel@tonic-gate */ 353*0Sstevel@tonic-gate get_badsec() 354*0Sstevel@tonic-gate { 355*0Sstevel@tonic-gate int cnt; 356*0Sstevel@tonic-gate struct badsec_lst *blc_p; 357*0Sstevel@tonic-gate daddr_t curbad; 358*0Sstevel@tonic-gate long maxsec = (long)dkg.dkg_nhead *dkg.dkg_ncyl *dkg.dkg_nsect; 359*0Sstevel@tonic-gate struct alts_ent *growbadp; 360*0Sstevel@tonic-gate int i; 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate cnt = count_badsec(); 363*0Sstevel@tonic-gate if (!cnt) { 364*0Sstevel@tonic-gate ap->ap_gbadp = NULL; 365*0Sstevel@tonic-gate ap->ap_gbadcnt = 0; 366*0Sstevel@tonic-gate } 367*0Sstevel@tonic-gate else { 368*0Sstevel@tonic-gate ap->ap_gbadp = (struct alts_ent *) malloc(cnt*ALTS_ENT_SIZE); 369*0Sstevel@tonic-gate memset(ap->ap_gbadp,0,cnt*ALTS_ENT_SIZE); 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate for (growbadp=ap->ap_gbadp, cnt=0, blc_p=badsl_chain; 372*0Sstevel@tonic-gate blc_p; blc_p=blc_p->bl_nxt) { 373*0Sstevel@tonic-gate for (i=0; i<blc_p->bl_cnt; i++) { 374*0Sstevel@tonic-gate curbad = blc_p->bl_sec[i]; 375*0Sstevel@tonic-gate if (curbad < (daddr_t)dkg.dkg_nsect) { 376*0Sstevel@tonic-gate fprintf(stderr, 377*0Sstevel@tonic-gate "Ignoring bad sector %ld which is in first track of the drive.\n", curbad); 378*0Sstevel@tonic-gate continue; 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate if (curbad >= maxsec) { 381*0Sstevel@tonic-gate fprintf(stderr, 382*0Sstevel@tonic-gate "Ignoring bad sector %ld which is past the end of the drive.\n", curbad); 383*0Sstevel@tonic-gate continue; 384*0Sstevel@tonic-gate } 385*0Sstevel@tonic-gate growbadp[cnt].bad_start = curbad; 386*0Sstevel@tonic-gate growbadp[cnt].bad_end = curbad; 387*0Sstevel@tonic-gate cnt++; 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate } 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate ap->ap_gbadcnt = cnt; 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate /* 395*0Sstevel@tonic-gate * count number of bad sector on list 396*0Sstevel@tonic-gate * merging the bad sector list from surface analysis and the 397*0Sstevel@tonic-gate * one given through the command line 398*0Sstevel@tonic-gate */ 399*0Sstevel@tonic-gate count_badsec() 400*0Sstevel@tonic-gate { 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate struct badsec_lst *blc_p; 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate if (!badsl_chain) 405*0Sstevel@tonic-gate badsl_chain = gbadsl_chain; 406*0Sstevel@tonic-gate else { 407*0Sstevel@tonic-gate for (blc_p = badsl_chain; blc_p->bl_nxt; blc_p=blc_p->bl_nxt) 408*0Sstevel@tonic-gate ; 409*0Sstevel@tonic-gate blc_p->bl_nxt = gbadsl_chain; 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate badsl_chain_cnt += gbadsl_chain_cnt; 413*0Sstevel@tonic-gate return(badsl_chain_cnt); 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gate /* 418*0Sstevel@tonic-gate * generate alternate entry table by merging the existing and 419*0Sstevel@tonic-gate * the new entry list. 420*0Sstevel@tonic-gate */ 421*0Sstevel@tonic-gate gen_alts_ent() { 422*0Sstevel@tonic-gate int ent_used; 423*0Sstevel@tonic-gate struct alts_ent *entp; 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate if (ap->ap_gbadcnt == 0) 426*0Sstevel@tonic-gate return; 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate ent_used = ap->ap_tblp->alts_ent_used + ap->ap_gbadcnt; 429*0Sstevel@tonic-gate ap->ap_ent_secsiz = byte_to_secsiz(ent_used*ALTS_ENT_SIZE,NBPSCTR); 430*0Sstevel@tonic-gate entp=(struct alts_ent *) malloc (ap->ap_ent_secsiz); 431*0Sstevel@tonic-gate ent_used = ent_merge(entp, ap->ap_entp, ap->ap_tblp->alts_ent_used, 432*0Sstevel@tonic-gate ap->ap_gbadp, ap->ap_gbadcnt); 433*0Sstevel@tonic-gate if (ap->ap_entp) 434*0Sstevel@tonic-gate free(ap->ap_entp); 435*0Sstevel@tonic-gate if (ap->ap_gbadp) 436*0Sstevel@tonic-gate free(ap->ap_gbadp); 437*0Sstevel@tonic-gate ap->ap_entp = entp; 438*0Sstevel@tonic-gate ap->ap_ent_secsiz = byte_to_secsiz(ent_used*ALTS_ENT_SIZE,NBPSCTR); 439*0Sstevel@tonic-gate ap->ap_tblp->alts_ent_used = ent_used; 440*0Sstevel@tonic-gate ap->ap_gbadp = NULL; 441*0Sstevel@tonic-gate ap->ap_gbadcnt = 0; 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate /* assign alternate sectors to the bad sectors */ 444*0Sstevel@tonic-gate assign_altsctr(); 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate /* allocate the alts_entry on disk skipping possible bad sectors */ 447*0Sstevel@tonic-gate ap->ap_tblp->alts_ent_base = 448*0Sstevel@tonic-gate altsmap_alloc(ap->ap_tblp->alts_map_base + ap->ap_map_sectot, 449*0Sstevel@tonic-gate ap->part.p_size, 450*0Sstevel@tonic-gate ap->ap_ent_secsiz / NBPSCTR, ALTS_MAP_UP); 451*0Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_base == NULL) { 452*0Sstevel@tonic-gate perror("Unable to allocate alternate entry table on disk: "); 453*0Sstevel@tonic-gate exit(65); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate ap->ap_tblp->alts_ent_end = ap->ap_tblp->alts_ent_base + 457*0Sstevel@tonic-gate (ap->ap_ent_secsiz / NBPSCTR) - 1; 458*0Sstevel@tonic-gate } 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate /* 462*0Sstevel@tonic-gate * assign alternate sectors for bad sector mapping 463*0Sstevel@tonic-gate */ 464*0Sstevel@tonic-gate assign_altsctr() 465*0Sstevel@tonic-gate { 466*0Sstevel@tonic-gate int i; 467*0Sstevel@tonic-gate int j; 468*0Sstevel@tonic-gate daddr_t alts_ind; 469*0Sstevel@tonic-gate int cluster; 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate for (i=0; i<ap->ap_tblp->alts_ent_used; i++) { 472*0Sstevel@tonic-gate if ((ap->ap_entp)[i].bad_start == ALTS_ENT_EMPTY) 473*0Sstevel@tonic-gate continue; 474*0Sstevel@tonic-gate if ((ap->ap_entp)[i].good_start != 0) 475*0Sstevel@tonic-gate continue; 476*0Sstevel@tonic-gate cluster = (ap->ap_entp)[i].bad_end-(ap->ap_entp)[i].bad_start +1; 477*0Sstevel@tonic-gate alts_ind = 478*0Sstevel@tonic-gate altsmap_alloc(ap->part.p_size-1, ap->ap_tblp->alts_map_base + 479*0Sstevel@tonic-gate ap->ap_map_sectot - 1, cluster, ALTS_MAP_DOWN); 480*0Sstevel@tonic-gate if (alts_ind == NULL) { 481*0Sstevel@tonic-gate fprintf(stderr, "Unable to allocate alternates for bad starting sector %ld.\n", (ap->ap_entp)[i].bad_start); 482*0Sstevel@tonic-gate exit(65); 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate alts_ind = alts_ind - cluster + 1; 485*0Sstevel@tonic-gate (ap->ap_entp)[i].good_start =alts_ind +ap->part.p_start; 486*0Sstevel@tonic-gate for (j=0; j<cluster; j++) { 487*0Sstevel@tonic-gate (ap->ap_memmapp)[alts_ind+j] = ALTS_BAD; 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate } 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate } 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate /* 495*0Sstevel@tonic-gate * transform the disk image alts bit map to incore char map 496*0Sstevel@tonic-gate */ 497*0Sstevel@tonic-gate expand_map() 498*0Sstevel@tonic-gate { 499*0Sstevel@tonic-gate int i; 500*0Sstevel@tonic-gate 501*0Sstevel@tonic-gate for (i=0; i<ap->part.p_size; i++) { 502*0Sstevel@tonic-gate (ap->ap_memmapp)[i] = altsmap_getbit(i); 503*0Sstevel@tonic-gate } 504*0Sstevel@tonic-gate } 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate /* 507*0Sstevel@tonic-gate * transform the incore alts char map to the disk image bit map 508*0Sstevel@tonic-gate */ 509*0Sstevel@tonic-gate compress_map() 510*0Sstevel@tonic-gate { 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate int i; 513*0Sstevel@tonic-gate int bytesz; 514*0Sstevel@tonic-gate char mask = 0; 515*0Sstevel@tonic-gate int maplen=0; 516*0Sstevel@tonic-gate 517*0Sstevel@tonic-gate for (i=0, bytesz=7; i<ap->part.p_size; i++) { 518*0Sstevel@tonic-gate mask |= ((ap->ap_memmapp)[i] << bytesz--); 519*0Sstevel@tonic-gate if (bytesz < 0) { 520*0Sstevel@tonic-gate (ap->ap_mapp)[maplen++] = mask; 521*0Sstevel@tonic-gate bytesz = 7; 522*0Sstevel@tonic-gate mask = 0; 523*0Sstevel@tonic-gate } 524*0Sstevel@tonic-gate } 525*0Sstevel@tonic-gate /* 526*0Sstevel@tonic-gate * if partition size != multiple number of bytes 527*0Sstevel@tonic-gate * then record the last partial byte 528*0Sstevel@tonic-gate */ 529*0Sstevel@tonic-gate if (bytesz != 7) 530*0Sstevel@tonic-gate (ap->ap_mapp)[maplen] = mask; 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate } 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate /* 535*0Sstevel@tonic-gate * given a bad sector number, search in the alts bit map 536*0Sstevel@tonic-gate * and identify the sector as good or bad 537*0Sstevel@tonic-gate */ 538*0Sstevel@tonic-gate altsmap_getbit(badsec) 539*0Sstevel@tonic-gate daddr_t badsec; 540*0Sstevel@tonic-gate { 541*0Sstevel@tonic-gate int slot = badsec / 8; 542*0Sstevel@tonic-gate int field = badsec % 8; 543*0Sstevel@tonic-gate unchar mask; 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate mask = ALTS_BAD<<7; 546*0Sstevel@tonic-gate mask >>= field; 547*0Sstevel@tonic-gate if ((ap->ap_mapp)[slot] & mask) 548*0Sstevel@tonic-gate return(ALTS_BAD); 549*0Sstevel@tonic-gate return(ALTS_GOOD); 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate /* 554*0Sstevel@tonic-gate * allocate a range of sectors from the alternate partition 555*0Sstevel@tonic-gate */ 556*0Sstevel@tonic-gate altsmap_alloc(srt_ind, end_ind, cnt, dir) 557*0Sstevel@tonic-gate daddr_t srt_ind; 558*0Sstevel@tonic-gate daddr_t end_ind; 559*0Sstevel@tonic-gate int cnt; 560*0Sstevel@tonic-gate int dir; 561*0Sstevel@tonic-gate { 562*0Sstevel@tonic-gate int i; 563*0Sstevel@tonic-gate int total; 564*0Sstevel@tonic-gate int first_ind; 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate for (i=srt_ind, first_ind=srt_ind, total=0; i!=end_ind; i+=dir) { 567*0Sstevel@tonic-gate if ((ap->ap_memmapp)[i] == ALTS_BAD) { 568*0Sstevel@tonic-gate total = 0; 569*0Sstevel@tonic-gate first_ind = i + dir; 570*0Sstevel@tonic-gate continue; 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate total++; 573*0Sstevel@tonic-gate if (total == cnt) 574*0Sstevel@tonic-gate return(first_ind); 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate } 577*0Sstevel@tonic-gate return(NULL); 578*0Sstevel@tonic-gate } 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate 581*0Sstevel@tonic-gate 582*0Sstevel@tonic-gate /* 583*0Sstevel@tonic-gate * bubble sort the entry table into ascending order 584*0Sstevel@tonic-gate */ 585*0Sstevel@tonic-gate ent_sort(buf, cnt) 586*0Sstevel@tonic-gate struct alts_ent buf[]; 587*0Sstevel@tonic-gate int cnt; 588*0Sstevel@tonic-gate { 589*0Sstevel@tonic-gate struct alts_ent temp; 590*0Sstevel@tonic-gate int flag; 591*0Sstevel@tonic-gate int i,j; 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate for (i=0; i<cnt-1; i++) { 594*0Sstevel@tonic-gate temp = buf[cnt-1]; 595*0Sstevel@tonic-gate flag = 1; 596*0Sstevel@tonic-gate 597*0Sstevel@tonic-gate for (j=cnt-1; j>i; j--) { 598*0Sstevel@tonic-gate if (buf[j-1].bad_start < temp.bad_start) { 599*0Sstevel@tonic-gate buf[j] = temp; 600*0Sstevel@tonic-gate temp = buf[j-1]; 601*0Sstevel@tonic-gate } else { 602*0Sstevel@tonic-gate buf[j] = buf[j-1]; 603*0Sstevel@tonic-gate flag = 0; 604*0Sstevel@tonic-gate } 605*0Sstevel@tonic-gate } 606*0Sstevel@tonic-gate buf[i] = temp; 607*0Sstevel@tonic-gate if (flag) break; 608*0Sstevel@tonic-gate } 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate } 611*0Sstevel@tonic-gate 612*0Sstevel@tonic-gate 613*0Sstevel@tonic-gate /* 614*0Sstevel@tonic-gate * compress all the contiguous bad sectors into a single entry 615*0Sstevel@tonic-gate * in the entry table. The entry table must be sorted into ascending 616*0Sstevel@tonic-gate * before the compression. 617*0Sstevel@tonic-gate */ 618*0Sstevel@tonic-gate ent_compress(buf, cnt) 619*0Sstevel@tonic-gate struct alts_ent buf[]; 620*0Sstevel@tonic-gate int cnt; 621*0Sstevel@tonic-gate { 622*0Sstevel@tonic-gate int keyp; 623*0Sstevel@tonic-gate int movp; 624*0Sstevel@tonic-gate int i; 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gate for (i=0; i<cnt; i++) { 627*0Sstevel@tonic-gate if (buf[i].bad_start == ALTS_ENT_EMPTY) 628*0Sstevel@tonic-gate continue; 629*0Sstevel@tonic-gate for (keyp=i, movp=i+1; movp<cnt; movp++) { 630*0Sstevel@tonic-gate if (buf[movp].bad_start == ALTS_ENT_EMPTY) 631*0Sstevel@tonic-gate continue; 632*0Sstevel@tonic-gate if (buf[keyp].bad_end+1 != buf[movp].bad_start) 633*0Sstevel@tonic-gate break; 634*0Sstevel@tonic-gate buf[keyp].bad_end++; 635*0Sstevel@tonic-gate buf[movp].bad_start = ALTS_ENT_EMPTY; 636*0Sstevel@tonic-gate } 637*0Sstevel@tonic-gate if (movp == cnt) break; 638*0Sstevel@tonic-gate } 639*0Sstevel@tonic-gate } 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate /* 643*0Sstevel@tonic-gate * merging two entry tables into a single table. In addition, 644*0Sstevel@tonic-gate * all empty slots in the entry table will be removed. 645*0Sstevel@tonic-gate */ 646*0Sstevel@tonic-gate ent_merge(buf, list1, lcnt1, list2, lcnt2) 647*0Sstevel@tonic-gate struct alts_ent buf[]; 648*0Sstevel@tonic-gate struct alts_ent list1[]; 649*0Sstevel@tonic-gate int lcnt1; 650*0Sstevel@tonic-gate struct alts_ent list2[]; 651*0Sstevel@tonic-gate int lcnt2; 652*0Sstevel@tonic-gate { 653*0Sstevel@tonic-gate int i; 654*0Sstevel@tonic-gate int j1,j2; 655*0Sstevel@tonic-gate 656*0Sstevel@tonic-gate for (i=0, j1=0, j2=0; j1<lcnt1 && j2<lcnt2;) { 657*0Sstevel@tonic-gate if (list1[j1].bad_start == ALTS_ENT_EMPTY) { 658*0Sstevel@tonic-gate j1++; 659*0Sstevel@tonic-gate continue; 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate if (list2[j2].bad_start == ALTS_ENT_EMPTY) { 662*0Sstevel@tonic-gate j2++; 663*0Sstevel@tonic-gate continue; 664*0Sstevel@tonic-gate } 665*0Sstevel@tonic-gate if (list1[j1].bad_start < list2[j2].bad_start) 666*0Sstevel@tonic-gate buf[i++] = list1[j1++]; 667*0Sstevel@tonic-gate else 668*0Sstevel@tonic-gate buf[i++] = list2[j2++]; 669*0Sstevel@tonic-gate } 670*0Sstevel@tonic-gate for (; j1<lcnt1; j1++) { 671*0Sstevel@tonic-gate if (list1[j1].bad_start == ALTS_ENT_EMPTY) 672*0Sstevel@tonic-gate continue; 673*0Sstevel@tonic-gate buf[i++] = list1[j1]; 674*0Sstevel@tonic-gate } 675*0Sstevel@tonic-gate for (; j2<lcnt2; j2++) { 676*0Sstevel@tonic-gate if (list2[j2].bad_start == ALTS_ENT_EMPTY) 677*0Sstevel@tonic-gate continue; 678*0Sstevel@tonic-gate buf[i++] = list2[j2]; 679*0Sstevel@tonic-gate } 680*0Sstevel@tonic-gate return (i); 681*0Sstevel@tonic-gate } 682*0Sstevel@tonic-gate 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate /* 685*0Sstevel@tonic-gate * binary search for bad sector in the alternate entry table 686*0Sstevel@tonic-gate */ 687*0Sstevel@tonic-gate ent_bsearch(buf, cnt, key) 688*0Sstevel@tonic-gate struct alts_ent buf[]; 689*0Sstevel@tonic-gate int cnt; 690*0Sstevel@tonic-gate struct alts_ent *key; 691*0Sstevel@tonic-gate { 692*0Sstevel@tonic-gate int i; 693*0Sstevel@tonic-gate int ind; 694*0Sstevel@tonic-gate int interval; 695*0Sstevel@tonic-gate int mystatus = -1; 696*0Sstevel@tonic-gate 697*0Sstevel@tonic-gate if (!cnt) return (mystatus); 698*0Sstevel@tonic-gate 699*0Sstevel@tonic-gate for (i=1; i<=cnt; i<<=1) 700*0Sstevel@tonic-gate ind=i; 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gate for (interval=ind; interval; ) { 703*0Sstevel@tonic-gate /* 704*0Sstevel@tonic-gate printf("ind= %d, intv= %d; ",ind, interval); 705*0Sstevel@tonic-gate */ 706*0Sstevel@tonic-gate if ((key->bad_start >= buf[ind-1].bad_start) && 707*0Sstevel@tonic-gate (key->bad_start <= buf[ind-1].bad_end)) { 708*0Sstevel@tonic-gate return(mystatus=ind-1); 709*0Sstevel@tonic-gate } else { 710*0Sstevel@tonic-gate interval >>= 1; 711*0Sstevel@tonic-gate if (!interval) break; 712*0Sstevel@tonic-gate if (key->bad_start < buf[ind-1].bad_start) { 713*0Sstevel@tonic-gate ind = ind - interval; 714*0Sstevel@tonic-gate } else { 715*0Sstevel@tonic-gate /* if key is larger than the last element then break */ 716*0Sstevel@tonic-gate if (ind == cnt) break; 717*0Sstevel@tonic-gate if ((ind+interval) <= cnt) 718*0Sstevel@tonic-gate ind += interval; 719*0Sstevel@tonic-gate } 720*0Sstevel@tonic-gate } 721*0Sstevel@tonic-gate } 722*0Sstevel@tonic-gate return(mystatus); 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate /* 726*0Sstevel@tonic-gate * check for bad sector in assigned alternate sectors 727*0Sstevel@tonic-gate */ 728*0Sstevel@tonic-gate chk_bad_altsctr(badsec) 729*0Sstevel@tonic-gate daddr_t badsec; 730*0Sstevel@tonic-gate { 731*0Sstevel@tonic-gate int i; 732*0Sstevel@tonic-gate int j; 733*0Sstevel@tonic-gate daddr_t numsec; 734*0Sstevel@tonic-gate int mystatus = FAILURE; 735*0Sstevel@tonic-gate int cnt = ap->ap_tblp->alts_ent_used; 736*0Sstevel@tonic-gate daddr_t intv[3]; 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate for (i=0; i<cnt; i++) { 739*0Sstevel@tonic-gate numsec = (ap->ap_entp)[i].bad_end - (ap->ap_entp)[i].bad_start; 740*0Sstevel@tonic-gate if ((badsec >= (ap->ap_entp)[i].good_start) && 741*0Sstevel@tonic-gate (badsec <= ((ap->ap_entp)[i].good_start + numsec))) { 742*0Sstevel@tonic-gate fprintf(stderr, "Bad sector %ld is an assigned alternate sector.\n", badsec); 743*0Sstevel@tonic-gate exit(66); 744*0Sstevel@tonic-gate /* 745*0Sstevel@tonic-gate if (!numsec) { 746*0Sstevel@tonic-gate (ap->ap_entp)[i].good_start = 0; 747*0Sstevel@tonic-gate return(mystatus); 748*0Sstevel@tonic-gate } 749*0Sstevel@tonic-gate intv[0] = badsec - (ap->ap_entp)[i].good_start; 750*0Sstevel@tonic-gate intv[1] = 1; 751*0Sstevel@tonic-gate intv[2] = (ap->ap_entp)[i].good_start + numsec - badsec; 752*0Sstevel@tonic-gate */ 753*0Sstevel@tonic-gate } 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate /* the bad sector has already been identified as bad */ 756*0Sstevel@tonic-gate return(mystatus=SUCCESS); 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate /* 762*0Sstevel@tonic-gate * print_altsec () -- print alternate sector information 763*0Sstevel@tonic-gate */ 764*0Sstevel@tonic-gate print_altsec(part) 765*0Sstevel@tonic-gate struct partition *part; 766*0Sstevel@tonic-gate { 767*0Sstevel@tonic-gate ap->ap_tblp = NULL; 768*0Sstevel@tonic-gate ap->ap_flag &= ~ALTS_ADDPART; 769*0Sstevel@tonic-gate read_altsctr(part, 0); 770*0Sstevel@tonic-gate print_altsctr(); 771*0Sstevel@tonic-gate return(SUCCESS); 772*0Sstevel@tonic-gate } 773*0Sstevel@tonic-gate 774*0Sstevel@tonic-gate print_altsctr() 775*0Sstevel@tonic-gate { 776*0Sstevel@tonic-gate int i; 777*0Sstevel@tonic-gate int totalloc; 778*0Sstevel@tonic-gate int avail; 779*0Sstevel@tonic-gate 780*0Sstevel@tonic-gate /* find # of available alternate sectors */ 781*0Sstevel@tonic-gate for (i=0, totalloc=0; i<ap->part.p_size; i++) { 782*0Sstevel@tonic-gate if ((ap->ap_memmapp)[i]) 783*0Sstevel@tonic-gate totalloc++; 784*0Sstevel@tonic-gate } 785*0Sstevel@tonic-gate /* 786*0Sstevel@tonic-gate * available = size of partition - allocated sectors/bad sectors 787*0Sstevel@tonic-gate * - partition table - partition map 788*0Sstevel@tonic-gate * - entry table 789*0Sstevel@tonic-gate */ 790*0Sstevel@tonic-gate avail = ap->part.p_size - totalloc; 791*0Sstevel@tonic-gate avail = avail - (ap->ap_tbl_secsiz/NBPSCTR) 792*0Sstevel@tonic-gate - ap->ap_map_sectot; 793*0Sstevel@tonic-gate avail = avail-(ap->ap_tblp->alts_ent_end -ap->ap_tblp->alts_ent_base+1); 794*0Sstevel@tonic-gate if (avail < 0) avail = 0; 795*0Sstevel@tonic-gate 796*0Sstevel@tonic-gate printf("\nALTERNATE SECTOR/TRACK MAPPING TABLE:\n"); 797*0Sstevel@tonic-gate printf("\nBad Sector Start\tAlternate Sector Start\t\tCount\n"); 798*0Sstevel@tonic-gate 799*0Sstevel@tonic-gate for (i=0; i<ap->ap_tblp->alts_ent_used; i++) { 800*0Sstevel@tonic-gate printf("\t%ld\t ->\t\t%ld\t\t\t %ld\n", 801*0Sstevel@tonic-gate (ap->ap_entp)[i].bad_start, 802*0Sstevel@tonic-gate (ap->ap_entp)[i].good_start, 803*0Sstevel@tonic-gate ((ap->ap_entp)[i].bad_end - (ap->ap_entp)[i].bad_start + 1)); 804*0Sstevel@tonic-gate } 805*0Sstevel@tonic-gate printf("\n %ld alternate sector(s) left for allocation.\n", avail); 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate } 808*0Sstevel@tonic-gate 809*0Sstevel@tonic-gate absdsk_io(fd, srtsec, bufp, len, ioflag) 810*0Sstevel@tonic-gate int fd; 811*0Sstevel@tonic-gate uint srtsec; 812*0Sstevel@tonic-gate char *bufp; 813*0Sstevel@tonic-gate uint len; 814*0Sstevel@tonic-gate int ioflag; 815*0Sstevel@tonic-gate { 816*0Sstevel@tonic-gate int rc; 817*0Sstevel@tonic-gate 818*0Sstevel@tonic-gate if (lseek (fd, srtsec * NBPSCTR, SEEK_SET) == -1) 819*0Sstevel@tonic-gate return(FAILURE); 820*0Sstevel@tonic-gate switch (ioflag) 821*0Sstevel@tonic-gate { 822*0Sstevel@tonic-gate case CMD_READ: 823*0Sstevel@tonic-gate rc = read (fd, bufp, len); 824*0Sstevel@tonic-gate break; 825*0Sstevel@tonic-gate case CMD_WRITE: 826*0Sstevel@tonic-gate rc = write (fd, bufp, len); 827*0Sstevel@tonic-gate break; 828*0Sstevel@tonic-gate default: 829*0Sstevel@tonic-gate break; 830*0Sstevel@tonic-gate } 831*0Sstevel@tonic-gate if (rc == -1) 832*0Sstevel@tonic-gate return(FAILURE); 833*0Sstevel@tonic-gate return(SUCCESS); 834*0Sstevel@tonic-gate } 835