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