10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*362Sbg159949 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ 280Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ 290Sstevel@tonic-gate /* All Rights Reserved */ 300Sstevel@tonic-gate 310Sstevel@tonic-gate /* 320Sstevel@tonic-gate * Copyrighted as an unpublished work. 330Sstevel@tonic-gate * (c) Copyright INTERACTIVE Systems Corporation 1986, 1988, 1990 340Sstevel@tonic-gate * All rights reserved. 350Sstevel@tonic-gate */ 360Sstevel@tonic-gate 370Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include <sys/types.h> 400Sstevel@tonic-gate #include <ctype.h> 410Sstevel@tonic-gate #include <fcntl.h> 420Sstevel@tonic-gate #include <malloc.h> 430Sstevel@tonic-gate #include <sys/stat.h> 440Sstevel@tonic-gate #include <sys/swap.h> 450Sstevel@tonic-gate #include <stdio.h> 460Sstevel@tonic-gate #include <string.h> 470Sstevel@tonic-gate #include <sys/vtoc.h> 480Sstevel@tonic-gate #include <sys/param.h> 490Sstevel@tonic-gate #include <sys/dkio.h> 500Sstevel@tonic-gate #include <sys/dktp/altsctr.h> 510Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 520Sstevel@tonic-gate #include "badsec.h" 530Sstevel@tonic-gate 540Sstevel@tonic-gate #define FAILURE 0 550Sstevel@tonic-gate #define SUCCESS 1 560Sstevel@tonic-gate 570Sstevel@tonic-gate #define CMD_READ 0 580Sstevel@tonic-gate #define CMD_WRITE 1 590Sstevel@tonic-gate 600Sstevel@tonic-gate struct badsec_lst *badsl_chain; 610Sstevel@tonic-gate int badsl_chain_cnt; 620Sstevel@tonic-gate struct badsec_lst *gbadsl_chain; 630Sstevel@tonic-gate int gbadsl_chain_cnt; 640Sstevel@tonic-gate 650Sstevel@tonic-gate extern struct dk_geom dkg; 660Sstevel@tonic-gate 670Sstevel@tonic-gate extern int alts_fd; 680Sstevel@tonic-gate 690Sstevel@tonic-gate struct alts_mempart alts_part = { 0, NULL, 0 }; 700Sstevel@tonic-gate struct alts_mempart *ap = &alts_part; /* pointer to incore alts tables */ 710Sstevel@tonic-gate 72*362Sbg159949 static void read_altsctr(struct partition *part, int badok); 73*362Sbg159949 static void chk_badsec (void); 74*362Sbg159949 static void init_altsctr (void); 75*362Sbg159949 void wr_altsctr (void); 76*362Sbg159949 static void get_badsec (void); 77*362Sbg159949 static int count_badsec (void); 78*362Sbg159949 static void gen_alts_ent (void); 79*362Sbg159949 static void assign_altsctr(void); 80*362Sbg159949 static void expand_map (void); 81*362Sbg159949 static void compress_map (void); 82*362Sbg159949 static int altsmap_getbit(daddr_t badsec); 83*362Sbg159949 static int altsmap_alloc(daddr_t srt_ind, daddr_t end_ind, int cnt, int dir); 84*362Sbg159949 static void ent_sort(struct alts_ent buf[], int cnt); 85*362Sbg159949 static void ent_compress(struct alts_ent buf[], int cnt); 86*362Sbg159949 static int ent_merge( 87*362Sbg159949 struct alts_ent buf[], 88*362Sbg159949 struct alts_ent list1[], 89*362Sbg159949 int lcnt1, 90*362Sbg159949 struct alts_ent list2[], 91*362Sbg159949 int lcnt2); 92*362Sbg159949 static int ent_bsearch(struct alts_ent buf[], int cnt, struct alts_ent *key); 93*362Sbg159949 static int chk_bad_altsctr(daddr_t badsec); 94*362Sbg159949 int print_altsec(struct partition *part); 95*362Sbg159949 static void print_altsctr(void); 96*362Sbg159949 static int absdsk_io(int fd, uint srtsec, char *bufp, uint len, int ioflag); 97*362Sbg159949 980Sstevel@tonic-gate /* 990Sstevel@tonic-gate * updatebadsec () -- update bad sector/track mapping tables 1000Sstevel@tonic-gate */ 101*362Sbg159949 int 102*362Sbg159949 updatebadsec(struct partition *part, int init_flag) 1030Sstevel@tonic-gate { 1040Sstevel@tonic-gate if (init_flag) 1050Sstevel@tonic-gate ap->ap_flag |= ALTS_ADDPART; 1060Sstevel@tonic-gate get_badsec(); 1070Sstevel@tonic-gate read_altsctr(part, 1); 1080Sstevel@tonic-gate ent_sort(ap->ap_gbadp, ap->ap_gbadcnt); 1090Sstevel@tonic-gate ent_compress(ap->ap_gbadp, ap->ap_gbadcnt); 1100Sstevel@tonic-gate gen_alts_ent(); 1110Sstevel@tonic-gate compress_map(); 1120Sstevel@tonic-gate return(SUCCESS); 1130Sstevel@tonic-gate } 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate /* 1160Sstevel@tonic-gate * read_altsctr( ptr to alternate sector partition ) 1170Sstevel@tonic-gate * -- read the alternate sector partition tables 1180Sstevel@tonic-gate */ 119*362Sbg159949 static void 120*362Sbg159949 read_altsctr(struct partition *part, int badok) 1210Sstevel@tonic-gate { 1220Sstevel@tonic-gate int ret; 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate if (ap->ap_tblp == NULL) { 1250Sstevel@tonic-gate /* allocate buffer for the alts partition table (sector size) */ 1260Sstevel@tonic-gate ap->ap_tbl_secsiz = byte_to_secsiz(ALTS_PARTTBL_SIZE,NBPSCTR); 1270Sstevel@tonic-gate ap->ap_tblp = (struct alts_parttbl *)malloc(ap->ap_tbl_secsiz); 1280Sstevel@tonic-gate if (ap->ap_tblp == NULL) { 1290Sstevel@tonic-gate fprintf(stderr, "Unable to malloc alternate partition table.\n"); 1300Sstevel@tonic-gate exit(50); 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* allocate buffer for the alts partition map (sector size) */ 1340Sstevel@tonic-gate /* buffers include the disk image bit map */ 1350Sstevel@tonic-gate /* and the incore transformed char map */ 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate if ((ap->ap_memmapp = (unchar *)malloc(part->p_size)) == NULL) { 1380Sstevel@tonic-gate fprintf(stderr, "Unable to malloc incore alternate partition map.\n"); 1390Sstevel@tonic-gate exit(51); 1400Sstevel@tonic-gate } 1410Sstevel@tonic-gate ap->ap_tblp->alts_map_len = (part->p_size + 8 - 1) / 8; 1420Sstevel@tonic-gate ap->ap_map_secsiz=byte_to_secsiz(ap->ap_tblp->alts_map_len,NBPSCTR); 1430Sstevel@tonic-gate ap->ap_map_sectot = ap->ap_map_secsiz / NBPSCTR; 1440Sstevel@tonic-gate if ((ap->ap_mapp = (unchar *)malloc(ap->ap_map_secsiz)) == NULL) { 1450Sstevel@tonic-gate fprintf(stderr, "Unable to malloc alternate partition map.\n"); 1460Sstevel@tonic-gate exit(52); 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate /* clear the buffers to zero */ 1490Sstevel@tonic-gate memset(ap->ap_memmapp,0,part->p_size); 1500Sstevel@tonic-gate memset(ap->ap_mapp,0,ap->ap_map_secsiz); 1510Sstevel@tonic-gate ap->part = *part; /* struct copy */ 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate /* 1540Sstevel@tonic-gate * if add alternate partition flag is set, then install the partition 1550Sstevel@tonic-gate * otherwise read the alts partition info from disk 1560Sstevel@tonic-gate * if failed, then assume the first installation 1570Sstevel@tonic-gate */ 1580Sstevel@tonic-gate if (ap->ap_flag & ALTS_ADDPART) 1590Sstevel@tonic-gate { 1600Sstevel@tonic-gate fprintf(stderr, "WARNING: Manually initializing alternate table.\n"); 1610Sstevel@tonic-gate init_altsctr(); 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate else { 1640Sstevel@tonic-gate if (get_altsctr(badok) == SUCCESS) 1650Sstevel@tonic-gate chk_badsec(); 1660Sstevel@tonic-gate else 1670Sstevel@tonic-gate init_altsctr(); 1680Sstevel@tonic-gate } 1690Sstevel@tonic-gate } 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate /* 1740Sstevel@tonic-gate * checking duplicate bad sectors or bad sectors in ALTSCTR partition 1750Sstevel@tonic-gate */ 176*362Sbg159949 static void 177*362Sbg159949 chk_badsec(void) 1780Sstevel@tonic-gate { 1790Sstevel@tonic-gate daddr_t badsec; 1800Sstevel@tonic-gate daddr_t altsp_srtsec = ap->part.p_start; 1810Sstevel@tonic-gate daddr_t altsp_endsec = ap->part.p_start + ap->part.p_size - 1; 1820Sstevel@tonic-gate int cnt; 1830Sstevel@tonic-gate int status; 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate for (cnt=0; cnt < ap->ap_gbadcnt; cnt++) { 1860Sstevel@tonic-gate badsec = (ap->ap_gbadp)[cnt].bad_start; 1870Sstevel@tonic-gate /* if bad sector is within the ATLSCTR partition */ 1880Sstevel@tonic-gate if ((badsec >= altsp_srtsec) && (badsec <= altsp_endsec)) { 1890Sstevel@tonic-gate if ((ap->ap_memmapp)[badsec - altsp_srtsec] != ALTS_BAD) { 1900Sstevel@tonic-gate if ((badsec >= altsp_srtsec) && (badsec <= (altsp_srtsec + 1910Sstevel@tonic-gate ap->ap_tbl_secsiz / NBPSCTR - 1))) { 1920Sstevel@tonic-gate fprintf(stderr, "Alternate partition information table is bad.\n"); 1930Sstevel@tonic-gate exit(53); 1940Sstevel@tonic-gate } 1950Sstevel@tonic-gate if ((badsec >= altsp_srtsec+ap->ap_tblp->alts_map_base) && 1960Sstevel@tonic-gate (badsec <= (altsp_srtsec + ap->ap_tblp->alts_map_base + 1970Sstevel@tonic-gate ap->ap_map_sectot - 1))) { 1980Sstevel@tonic-gate fprintf(stderr, "Alternate partition map is bad.\n"); 1990Sstevel@tonic-gate exit(54); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate if ((badsec >= altsp_srtsec+ap->ap_tblp->alts_ent_base) && 2020Sstevel@tonic-gate (badsec <= (altsp_srtsec + ap->ap_tblp->alts_ent_base + 2030Sstevel@tonic-gate ap->ap_ent_secsiz / NBPSCTR - 1))) { 2040Sstevel@tonic-gate fprintf(stderr, "Alternate partition entry table is bad.\n"); 2050Sstevel@tonic-gate exit(55); 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate (ap->ap_memmapp)[badsec - altsp_srtsec] = ALTS_BAD; 2080Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 2090Sstevel@tonic-gate } else { 2100Sstevel@tonic-gate status = chk_bad_altsctr(badsec); 2110Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate } else { 2140Sstevel@tonic-gate /* 2150Sstevel@tonic-gate * binary search for bad sector in the alts entry table 2160Sstevel@tonic-gate */ 2170Sstevel@tonic-gate status = ent_bsearch(ap->ap_entp, ap->ap_tblp->alts_ent_used, 2180Sstevel@tonic-gate &((ap->ap_gbadp)[cnt]) ); 2190Sstevel@tonic-gate /* 2200Sstevel@tonic-gate * if the bad sector had already been remapped(found in alts_entry) 2210Sstevel@tonic-gate * then ignore the bad sector 2220Sstevel@tonic-gate */ 2230Sstevel@tonic-gate if (status != -1) { 2240Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate } 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate /* 2350Sstevel@tonic-gate * initialize the alternate partition tables 2360Sstevel@tonic-gate */ 237*362Sbg159949 static void 238*362Sbg159949 init_altsctr(void) 2390Sstevel@tonic-gate { 2400Sstevel@tonic-gate daddr_t badsec; 2410Sstevel@tonic-gate daddr_t altsp_srtsec = ap->part.p_start; 2420Sstevel@tonic-gate daddr_t altsp_endsec = ap->part.p_start + ap->part.p_size - 1; 2430Sstevel@tonic-gate int cnt; 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate ap->ap_entp = NULL; 2460Sstevel@tonic-gate ap->ap_ent_secsiz = 0; 2470Sstevel@tonic-gate ap->ap_tblp->alts_sanity = ALTS_SANITY; 2480Sstevel@tonic-gate ap->ap_tblp->alts_version= ALTS_VERSION1; 2490Sstevel@tonic-gate ap->ap_tblp->alts_map_len = (ap->part.p_size + 8 - 1) / 8; 2500Sstevel@tonic-gate ap->ap_tblp->alts_ent_used = 0; 2510Sstevel@tonic-gate ap->ap_tblp->alts_ent_base = 0; 2520Sstevel@tonic-gate ap->ap_tblp->alts_ent_end = 0; 2530Sstevel@tonic-gate ap->ap_tblp->alts_resv_base = ap->part.p_size - 1; 2540Sstevel@tonic-gate for (cnt=0; cnt<5; cnt++) 2550Sstevel@tonic-gate ap->ap_tblp->alts_pad[cnt]=0; 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate for (cnt=0; cnt < ap->ap_gbadcnt; cnt++) { 2580Sstevel@tonic-gate badsec = (ap->ap_gbadp)[cnt].bad_start; 2590Sstevel@tonic-gate if ((badsec >= altsp_srtsec) && (badsec <= altsp_endsec)) { 2600Sstevel@tonic-gate if (badsec == altsp_srtsec) { 2610Sstevel@tonic-gate fprintf(stderr, "First sector of alternate partition is bad.\n"); 2620Sstevel@tonic-gate exit(56); 2630Sstevel@tonic-gate } 2640Sstevel@tonic-gate (ap->ap_memmapp)[badsec - altsp_srtsec] = ALTS_BAD; 2650Sstevel@tonic-gate (ap->ap_gbadp)[cnt].bad_start = ALTS_ENT_EMPTY; 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate } 2680Sstevel@tonic-gate 2690Sstevel@tonic-gate /* allocate the alts_map on disk skipping possible bad sectors */ 2700Sstevel@tonic-gate ap->ap_tblp->alts_map_base = 2710Sstevel@tonic-gate altsmap_alloc(ap->ap_tbl_secsiz / NBPSCTR, 2720Sstevel@tonic-gate ap->part.p_size, ap->ap_map_sectot, ALTS_MAP_UP); 2730Sstevel@tonic-gate if (ap->ap_tblp->alts_map_base == NULL) { 2740Sstevel@tonic-gate perror("Unable to allocate alternate map on disk: "); 2750Sstevel@tonic-gate exit(57); 2760Sstevel@tonic-gate } 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate /* 2820Sstevel@tonic-gate * read the alternate partition tables from disk 2830Sstevel@tonic-gate */ 2840Sstevel@tonic-gate int 2850Sstevel@tonic-gate get_altsctr(badok) 2860Sstevel@tonic-gate int badok; 2870Sstevel@tonic-gate { 2880Sstevel@tonic-gate /* get alts partition table info */ 2890Sstevel@tonic-gate if (absdsk_io(alts_fd, 0, (char *)ap->ap_tblp, 2900Sstevel@tonic-gate ap->ap_tbl_secsiz,CMD_READ)==FAILURE) { 2910Sstevel@tonic-gate if (badok) 2920Sstevel@tonic-gate return(FAILURE); 2930Sstevel@tonic-gate perror("Unable to read alternate sector partition: "); 2940Sstevel@tonic-gate exit(58); 2950Sstevel@tonic-gate } 2960Sstevel@tonic-gate if (ap->ap_tblp->alts_sanity != ALTS_SANITY) { 2970Sstevel@tonic-gate if (badok) 2980Sstevel@tonic-gate return(FAILURE); 2990Sstevel@tonic-gate fprintf(stderr, "Bad alternate sector magic number.\n"); 3000Sstevel@tonic-gate exit(69); 3010Sstevel@tonic-gate } 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate /* get the alts map */ 3040Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_map_base, 3050Sstevel@tonic-gate (char *)ap->ap_mapp, ap->ap_map_secsiz, CMD_READ) == FAILURE) { 3060Sstevel@tonic-gate if (badok) 3070Sstevel@tonic-gate return(FAILURE); 3080Sstevel@tonic-gate perror("Unable to read alternate sector partition map: "); 3090Sstevel@tonic-gate exit(59); 3100Sstevel@tonic-gate } 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate /* transform the disk image bit-map to incore char map */ 3130Sstevel@tonic-gate expand_map(); 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_used == 0) { 3160Sstevel@tonic-gate ap->ap_entp = NULL; 3170Sstevel@tonic-gate ap->ap_ent_secsiz = 0; 3180Sstevel@tonic-gate } else { 3190Sstevel@tonic-gate ap->ap_ent_secsiz = byte_to_secsiz( 3200Sstevel@tonic-gate (ap->ap_tblp->alts_ent_used*ALTS_ENT_SIZE),NBPSCTR); 3210Sstevel@tonic-gate if ((ap->ap_entp = (struct alts_ent *)malloc(ap->ap_ent_secsiz)) == NULL) { 3220Sstevel@tonic-gate if (badok) 3230Sstevel@tonic-gate return(FAILURE); 3240Sstevel@tonic-gate fprintf(stderr, "Unable to malloc alternate sector entry table.\n"); 3250Sstevel@tonic-gate exit(60); 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate 3280Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_ent_base, 3290Sstevel@tonic-gate (char *)ap->ap_entp, ap->ap_ent_secsiz, 3300Sstevel@tonic-gate CMD_READ) ==FAILURE){ 3310Sstevel@tonic-gate if (badok) 3320Sstevel@tonic-gate return(FAILURE); 3330Sstevel@tonic-gate perror("Unable to read alternate sector entry table: "); 3340Sstevel@tonic-gate exit(61); 3350Sstevel@tonic-gate } 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate return(SUCCESS); 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate /* 3420Sstevel@tonic-gate * update the new alternate partition tables on disk 3430Sstevel@tonic-gate */ 344*362Sbg159949 void 345*362Sbg159949 wr_altsctr(void) 3460Sstevel@tonic-gate { 3470Sstevel@tonic-gate int mystatus = FAILURE; 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate if (ap->ap_tblp == NULL) 3500Sstevel@tonic-gate return; 351*362Sbg159949 if (absdsk_io(alts_fd, 0, (char *)ap->ap_tblp, 3520Sstevel@tonic-gate ap->ap_tbl_secsiz, CMD_WRITE) == FAILURE) { 3530Sstevel@tonic-gate perror("Unable to write alternate sector partition: "); 3540Sstevel@tonic-gate exit(62); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_map_base, 358*362Sbg159949 (char *)ap->ap_mapp, ap->ap_map_secsiz, CMD_WRITE) == FAILURE) { 3590Sstevel@tonic-gate perror("Unable to write alternate sector partition map: "); 3600Sstevel@tonic-gate exit(63); 3610Sstevel@tonic-gate } 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_used != 0) { 3640Sstevel@tonic-gate if (absdsk_io(alts_fd, ap->ap_tblp->alts_ent_base, 3650Sstevel@tonic-gate (char *)ap->ap_entp, ap->ap_ent_secsiz, 3660Sstevel@tonic-gate CMD_WRITE) == FAILURE) { 3670Sstevel@tonic-gate perror("Unable to write alternate sector entry table: "); 3680Sstevel@tonic-gate exit(64); 3690Sstevel@tonic-gate } 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate /* 3780Sstevel@tonic-gate * get a list of bad sector 3790Sstevel@tonic-gate */ 380*362Sbg159949 static void 381*362Sbg159949 get_badsec(void) 3820Sstevel@tonic-gate { 3830Sstevel@tonic-gate int cnt; 3840Sstevel@tonic-gate struct badsec_lst *blc_p; 3850Sstevel@tonic-gate daddr_t curbad; 3860Sstevel@tonic-gate long maxsec = (long)dkg.dkg_nhead *dkg.dkg_ncyl *dkg.dkg_nsect; 3870Sstevel@tonic-gate struct alts_ent *growbadp; 3880Sstevel@tonic-gate int i; 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate cnt = count_badsec(); 3910Sstevel@tonic-gate if (!cnt) { 3920Sstevel@tonic-gate ap->ap_gbadp = NULL; 3930Sstevel@tonic-gate ap->ap_gbadcnt = 0; 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate else { 3960Sstevel@tonic-gate ap->ap_gbadp = (struct alts_ent *) malloc(cnt*ALTS_ENT_SIZE); 3970Sstevel@tonic-gate memset(ap->ap_gbadp,0,cnt*ALTS_ENT_SIZE); 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate for (growbadp=ap->ap_gbadp, cnt=0, blc_p=badsl_chain; 4000Sstevel@tonic-gate blc_p; blc_p=blc_p->bl_nxt) { 4010Sstevel@tonic-gate for (i=0; i<blc_p->bl_cnt; i++) { 4020Sstevel@tonic-gate curbad = blc_p->bl_sec[i]; 4030Sstevel@tonic-gate if (curbad < (daddr_t)dkg.dkg_nsect) { 4040Sstevel@tonic-gate fprintf(stderr, 4050Sstevel@tonic-gate "Ignoring bad sector %ld which is in first track of the drive.\n", curbad); 4060Sstevel@tonic-gate continue; 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate if (curbad >= maxsec) { 4090Sstevel@tonic-gate fprintf(stderr, 4100Sstevel@tonic-gate "Ignoring bad sector %ld which is past the end of the drive.\n", curbad); 4110Sstevel@tonic-gate continue; 4120Sstevel@tonic-gate } 4130Sstevel@tonic-gate growbadp[cnt].bad_start = curbad; 4140Sstevel@tonic-gate growbadp[cnt].bad_end = curbad; 4150Sstevel@tonic-gate cnt++; 4160Sstevel@tonic-gate } 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate ap->ap_gbadcnt = cnt; 4200Sstevel@tonic-gate } 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate /* 4230Sstevel@tonic-gate * count number of bad sector on list 4240Sstevel@tonic-gate * merging the bad sector list from surface analysis and the 4250Sstevel@tonic-gate * one given through the command line 4260Sstevel@tonic-gate */ 427*362Sbg159949 static int 428*362Sbg159949 count_badsec(void) 4290Sstevel@tonic-gate { 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate struct badsec_lst *blc_p; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate if (!badsl_chain) 4340Sstevel@tonic-gate badsl_chain = gbadsl_chain; 4350Sstevel@tonic-gate else { 4360Sstevel@tonic-gate for (blc_p = badsl_chain; blc_p->bl_nxt; blc_p=blc_p->bl_nxt) 4370Sstevel@tonic-gate ; 4380Sstevel@tonic-gate blc_p->bl_nxt = gbadsl_chain; 4390Sstevel@tonic-gate } 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate badsl_chain_cnt += gbadsl_chain_cnt; 4420Sstevel@tonic-gate return(badsl_chain_cnt); 4430Sstevel@tonic-gate } 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate /* 4470Sstevel@tonic-gate * generate alternate entry table by merging the existing and 4480Sstevel@tonic-gate * the new entry list. 4490Sstevel@tonic-gate */ 450*362Sbg159949 static void 451*362Sbg159949 gen_alts_ent(void) 452*362Sbg159949 { 4530Sstevel@tonic-gate int ent_used; 4540Sstevel@tonic-gate struct alts_ent *entp; 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate if (ap->ap_gbadcnt == 0) 4570Sstevel@tonic-gate return; 4580Sstevel@tonic-gate 4590Sstevel@tonic-gate ent_used = ap->ap_tblp->alts_ent_used + ap->ap_gbadcnt; 4600Sstevel@tonic-gate ap->ap_ent_secsiz = byte_to_secsiz(ent_used*ALTS_ENT_SIZE,NBPSCTR); 4610Sstevel@tonic-gate entp=(struct alts_ent *) malloc (ap->ap_ent_secsiz); 4620Sstevel@tonic-gate ent_used = ent_merge(entp, ap->ap_entp, ap->ap_tblp->alts_ent_used, 4630Sstevel@tonic-gate ap->ap_gbadp, ap->ap_gbadcnt); 4640Sstevel@tonic-gate if (ap->ap_entp) 4650Sstevel@tonic-gate free(ap->ap_entp); 4660Sstevel@tonic-gate if (ap->ap_gbadp) 4670Sstevel@tonic-gate free(ap->ap_gbadp); 4680Sstevel@tonic-gate ap->ap_entp = entp; 4690Sstevel@tonic-gate ap->ap_ent_secsiz = byte_to_secsiz(ent_used*ALTS_ENT_SIZE,NBPSCTR); 4700Sstevel@tonic-gate ap->ap_tblp->alts_ent_used = ent_used; 4710Sstevel@tonic-gate ap->ap_gbadp = NULL; 4720Sstevel@tonic-gate ap->ap_gbadcnt = 0; 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate /* assign alternate sectors to the bad sectors */ 4750Sstevel@tonic-gate assign_altsctr(); 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate /* allocate the alts_entry on disk skipping possible bad sectors */ 4780Sstevel@tonic-gate ap->ap_tblp->alts_ent_base = 4790Sstevel@tonic-gate altsmap_alloc(ap->ap_tblp->alts_map_base + ap->ap_map_sectot, 4800Sstevel@tonic-gate ap->part.p_size, 4810Sstevel@tonic-gate ap->ap_ent_secsiz / NBPSCTR, ALTS_MAP_UP); 4820Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_base == NULL) { 4830Sstevel@tonic-gate perror("Unable to allocate alternate entry table on disk: "); 4840Sstevel@tonic-gate exit(65); 4850Sstevel@tonic-gate } 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate ap->ap_tblp->alts_ent_end = ap->ap_tblp->alts_ent_base + 4880Sstevel@tonic-gate (ap->ap_ent_secsiz / NBPSCTR) - 1; 4890Sstevel@tonic-gate } 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate /* 4930Sstevel@tonic-gate * assign alternate sectors for bad sector mapping 4940Sstevel@tonic-gate */ 495*362Sbg159949 static void 496*362Sbg159949 assign_altsctr(void) 4970Sstevel@tonic-gate { 4980Sstevel@tonic-gate int i; 4990Sstevel@tonic-gate int j; 5000Sstevel@tonic-gate daddr_t alts_ind; 5010Sstevel@tonic-gate int cluster; 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate for (i=0; i<ap->ap_tblp->alts_ent_used; i++) { 5040Sstevel@tonic-gate if ((ap->ap_entp)[i].bad_start == ALTS_ENT_EMPTY) 5050Sstevel@tonic-gate continue; 5060Sstevel@tonic-gate if ((ap->ap_entp)[i].good_start != 0) 5070Sstevel@tonic-gate continue; 5080Sstevel@tonic-gate cluster = (ap->ap_entp)[i].bad_end-(ap->ap_entp)[i].bad_start +1; 5090Sstevel@tonic-gate alts_ind = 5100Sstevel@tonic-gate altsmap_alloc(ap->part.p_size-1, ap->ap_tblp->alts_map_base + 5110Sstevel@tonic-gate ap->ap_map_sectot - 1, cluster, ALTS_MAP_DOWN); 5120Sstevel@tonic-gate if (alts_ind == NULL) { 5130Sstevel@tonic-gate fprintf(stderr, "Unable to allocate alternates for bad starting sector %ld.\n", (ap->ap_entp)[i].bad_start); 5140Sstevel@tonic-gate exit(65); 5150Sstevel@tonic-gate } 5160Sstevel@tonic-gate alts_ind = alts_ind - cluster + 1; 5170Sstevel@tonic-gate (ap->ap_entp)[i].good_start =alts_ind +ap->part.p_start; 5180Sstevel@tonic-gate for (j=0; j<cluster; j++) { 5190Sstevel@tonic-gate (ap->ap_memmapp)[alts_ind+j] = ALTS_BAD; 5200Sstevel@tonic-gate } 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate } 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate } 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate /* 5270Sstevel@tonic-gate * transform the disk image alts bit map to incore char map 5280Sstevel@tonic-gate */ 529*362Sbg159949 static void 530*362Sbg159949 expand_map(void) 5310Sstevel@tonic-gate { 5320Sstevel@tonic-gate int i; 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate for (i=0; i<ap->part.p_size; i++) { 5350Sstevel@tonic-gate (ap->ap_memmapp)[i] = altsmap_getbit(i); 5360Sstevel@tonic-gate } 5370Sstevel@tonic-gate } 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate /* 5400Sstevel@tonic-gate * transform the incore alts char map to the disk image bit map 5410Sstevel@tonic-gate */ 542*362Sbg159949 static void 543*362Sbg159949 compress_map(void) 5440Sstevel@tonic-gate { 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate int i; 5470Sstevel@tonic-gate int bytesz; 5480Sstevel@tonic-gate char mask = 0; 5490Sstevel@tonic-gate int maplen=0; 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate for (i=0, bytesz=7; i<ap->part.p_size; i++) { 5520Sstevel@tonic-gate mask |= ((ap->ap_memmapp)[i] << bytesz--); 5530Sstevel@tonic-gate if (bytesz < 0) { 5540Sstevel@tonic-gate (ap->ap_mapp)[maplen++] = mask; 5550Sstevel@tonic-gate bytesz = 7; 5560Sstevel@tonic-gate mask = 0; 5570Sstevel@tonic-gate } 5580Sstevel@tonic-gate } 5590Sstevel@tonic-gate /* 5600Sstevel@tonic-gate * if partition size != multiple number of bytes 5610Sstevel@tonic-gate * then record the last partial byte 5620Sstevel@tonic-gate */ 5630Sstevel@tonic-gate if (bytesz != 7) 5640Sstevel@tonic-gate (ap->ap_mapp)[maplen] = mask; 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate } 5670Sstevel@tonic-gate 5680Sstevel@tonic-gate /* 5690Sstevel@tonic-gate * given a bad sector number, search in the alts bit map 5700Sstevel@tonic-gate * and identify the sector as good or bad 5710Sstevel@tonic-gate */ 572*362Sbg159949 static int 573*362Sbg159949 altsmap_getbit(daddr_t badsec) 5740Sstevel@tonic-gate { 5750Sstevel@tonic-gate int slot = badsec / 8; 5760Sstevel@tonic-gate int field = badsec % 8; 5770Sstevel@tonic-gate unchar mask; 5780Sstevel@tonic-gate 5790Sstevel@tonic-gate mask = ALTS_BAD<<7; 5800Sstevel@tonic-gate mask >>= field; 5810Sstevel@tonic-gate if ((ap->ap_mapp)[slot] & mask) 5820Sstevel@tonic-gate return(ALTS_BAD); 5830Sstevel@tonic-gate return(ALTS_GOOD); 5840Sstevel@tonic-gate } 5850Sstevel@tonic-gate 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate /* 5880Sstevel@tonic-gate * allocate a range of sectors from the alternate partition 5890Sstevel@tonic-gate */ 590*362Sbg159949 static int 591*362Sbg159949 altsmap_alloc(daddr_t srt_ind, daddr_t end_ind, int cnt, int dir) 5920Sstevel@tonic-gate { 5930Sstevel@tonic-gate int i; 5940Sstevel@tonic-gate int total; 5950Sstevel@tonic-gate int first_ind; 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate for (i=srt_ind, first_ind=srt_ind, total=0; i!=end_ind; i+=dir) { 5980Sstevel@tonic-gate if ((ap->ap_memmapp)[i] == ALTS_BAD) { 5990Sstevel@tonic-gate total = 0; 6000Sstevel@tonic-gate first_ind = i + dir; 6010Sstevel@tonic-gate continue; 6020Sstevel@tonic-gate } 6030Sstevel@tonic-gate total++; 6040Sstevel@tonic-gate if (total == cnt) 6050Sstevel@tonic-gate return(first_ind); 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate } 608*362Sbg159949 return(0); 6090Sstevel@tonic-gate } 6100Sstevel@tonic-gate 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate 6130Sstevel@tonic-gate /* 6140Sstevel@tonic-gate * bubble sort the entry table into ascending order 6150Sstevel@tonic-gate */ 616*362Sbg159949 static void 617*362Sbg159949 ent_sort(struct alts_ent buf[], int cnt) 6180Sstevel@tonic-gate { 6190Sstevel@tonic-gate struct alts_ent temp; 6200Sstevel@tonic-gate int flag; 6210Sstevel@tonic-gate int i,j; 6220Sstevel@tonic-gate 6230Sstevel@tonic-gate for (i=0; i<cnt-1; i++) { 6240Sstevel@tonic-gate temp = buf[cnt-1]; 6250Sstevel@tonic-gate flag = 1; 6260Sstevel@tonic-gate 6270Sstevel@tonic-gate for (j=cnt-1; j>i; j--) { 6280Sstevel@tonic-gate if (buf[j-1].bad_start < temp.bad_start) { 6290Sstevel@tonic-gate buf[j] = temp; 6300Sstevel@tonic-gate temp = buf[j-1]; 6310Sstevel@tonic-gate } else { 6320Sstevel@tonic-gate buf[j] = buf[j-1]; 6330Sstevel@tonic-gate flag = 0; 6340Sstevel@tonic-gate } 6350Sstevel@tonic-gate } 6360Sstevel@tonic-gate buf[i] = temp; 6370Sstevel@tonic-gate if (flag) break; 6380Sstevel@tonic-gate } 6390Sstevel@tonic-gate 6400Sstevel@tonic-gate } 6410Sstevel@tonic-gate 6420Sstevel@tonic-gate 6430Sstevel@tonic-gate /* 6440Sstevel@tonic-gate * compress all the contiguous bad sectors into a single entry 6450Sstevel@tonic-gate * in the entry table. The entry table must be sorted into ascending 6460Sstevel@tonic-gate * before the compression. 6470Sstevel@tonic-gate */ 648*362Sbg159949 static void 649*362Sbg159949 ent_compress(struct alts_ent buf[], int cnt) 6500Sstevel@tonic-gate { 6510Sstevel@tonic-gate int keyp; 6520Sstevel@tonic-gate int movp; 6530Sstevel@tonic-gate int i; 6540Sstevel@tonic-gate 6550Sstevel@tonic-gate for (i=0; i<cnt; i++) { 6560Sstevel@tonic-gate if (buf[i].bad_start == ALTS_ENT_EMPTY) 6570Sstevel@tonic-gate continue; 6580Sstevel@tonic-gate for (keyp=i, movp=i+1; movp<cnt; movp++) { 6590Sstevel@tonic-gate if (buf[movp].bad_start == ALTS_ENT_EMPTY) 6600Sstevel@tonic-gate continue; 6610Sstevel@tonic-gate if (buf[keyp].bad_end+1 != buf[movp].bad_start) 6620Sstevel@tonic-gate break; 6630Sstevel@tonic-gate buf[keyp].bad_end++; 6640Sstevel@tonic-gate buf[movp].bad_start = ALTS_ENT_EMPTY; 6650Sstevel@tonic-gate } 6660Sstevel@tonic-gate if (movp == cnt) break; 6670Sstevel@tonic-gate } 6680Sstevel@tonic-gate } 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate 6710Sstevel@tonic-gate /* 6720Sstevel@tonic-gate * merging two entry tables into a single table. In addition, 6730Sstevel@tonic-gate * all empty slots in the entry table will be removed. 6740Sstevel@tonic-gate */ 675*362Sbg159949 static int 676*362Sbg159949 ent_merge( 677*362Sbg159949 struct alts_ent buf[], 678*362Sbg159949 struct alts_ent list1[], 679*362Sbg159949 int lcnt1, 680*362Sbg159949 struct alts_ent list2[], 681*362Sbg159949 int lcnt2) 6820Sstevel@tonic-gate { 6830Sstevel@tonic-gate int i; 6840Sstevel@tonic-gate int j1,j2; 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate for (i=0, j1=0, j2=0; j1<lcnt1 && j2<lcnt2;) { 6870Sstevel@tonic-gate if (list1[j1].bad_start == ALTS_ENT_EMPTY) { 6880Sstevel@tonic-gate j1++; 6890Sstevel@tonic-gate continue; 6900Sstevel@tonic-gate } 6910Sstevel@tonic-gate if (list2[j2].bad_start == ALTS_ENT_EMPTY) { 6920Sstevel@tonic-gate j2++; 6930Sstevel@tonic-gate continue; 6940Sstevel@tonic-gate } 6950Sstevel@tonic-gate if (list1[j1].bad_start < list2[j2].bad_start) 6960Sstevel@tonic-gate buf[i++] = list1[j1++]; 6970Sstevel@tonic-gate else 6980Sstevel@tonic-gate buf[i++] = list2[j2++]; 6990Sstevel@tonic-gate } 7000Sstevel@tonic-gate for (; j1<lcnt1; j1++) { 7010Sstevel@tonic-gate if (list1[j1].bad_start == ALTS_ENT_EMPTY) 7020Sstevel@tonic-gate continue; 7030Sstevel@tonic-gate buf[i++] = list1[j1]; 7040Sstevel@tonic-gate } 7050Sstevel@tonic-gate for (; j2<lcnt2; j2++) { 7060Sstevel@tonic-gate if (list2[j2].bad_start == ALTS_ENT_EMPTY) 7070Sstevel@tonic-gate continue; 7080Sstevel@tonic-gate buf[i++] = list2[j2]; 7090Sstevel@tonic-gate } 7100Sstevel@tonic-gate return (i); 7110Sstevel@tonic-gate } 7120Sstevel@tonic-gate 7130Sstevel@tonic-gate 7140Sstevel@tonic-gate /* 7150Sstevel@tonic-gate * binary search for bad sector in the alternate entry table 7160Sstevel@tonic-gate */ 717*362Sbg159949 static int 718*362Sbg159949 ent_bsearch(struct alts_ent buf[], int cnt, struct alts_ent *key) 7190Sstevel@tonic-gate { 7200Sstevel@tonic-gate int i; 7210Sstevel@tonic-gate int ind; 7220Sstevel@tonic-gate int interval; 7230Sstevel@tonic-gate int mystatus = -1; 7240Sstevel@tonic-gate 7250Sstevel@tonic-gate if (!cnt) return (mystatus); 7260Sstevel@tonic-gate 7270Sstevel@tonic-gate for (i=1; i<=cnt; i<<=1) 7280Sstevel@tonic-gate ind=i; 7290Sstevel@tonic-gate 7300Sstevel@tonic-gate for (interval=ind; interval; ) { 7310Sstevel@tonic-gate /* 7320Sstevel@tonic-gate printf("ind= %d, intv= %d; ",ind, interval); 7330Sstevel@tonic-gate */ 7340Sstevel@tonic-gate if ((key->bad_start >= buf[ind-1].bad_start) && 7350Sstevel@tonic-gate (key->bad_start <= buf[ind-1].bad_end)) { 7360Sstevel@tonic-gate return(mystatus=ind-1); 7370Sstevel@tonic-gate } else { 7380Sstevel@tonic-gate interval >>= 1; 7390Sstevel@tonic-gate if (!interval) break; 7400Sstevel@tonic-gate if (key->bad_start < buf[ind-1].bad_start) { 7410Sstevel@tonic-gate ind = ind - interval; 7420Sstevel@tonic-gate } else { 7430Sstevel@tonic-gate /* if key is larger than the last element then break */ 7440Sstevel@tonic-gate if (ind == cnt) break; 7450Sstevel@tonic-gate if ((ind+interval) <= cnt) 7460Sstevel@tonic-gate ind += interval; 7470Sstevel@tonic-gate } 7480Sstevel@tonic-gate } 7490Sstevel@tonic-gate } 7500Sstevel@tonic-gate return(mystatus); 7510Sstevel@tonic-gate } 7520Sstevel@tonic-gate 7530Sstevel@tonic-gate /* 7540Sstevel@tonic-gate * check for bad sector in assigned alternate sectors 7550Sstevel@tonic-gate */ 756*362Sbg159949 static int 757*362Sbg159949 chk_bad_altsctr(daddr_t badsec) 7580Sstevel@tonic-gate { 7590Sstevel@tonic-gate int i; 7600Sstevel@tonic-gate int j; 7610Sstevel@tonic-gate daddr_t numsec; 7620Sstevel@tonic-gate int mystatus = FAILURE; 7630Sstevel@tonic-gate int cnt = ap->ap_tblp->alts_ent_used; 7640Sstevel@tonic-gate daddr_t intv[3]; 7650Sstevel@tonic-gate 7660Sstevel@tonic-gate for (i=0; i<cnt; i++) { 7670Sstevel@tonic-gate numsec = (ap->ap_entp)[i].bad_end - (ap->ap_entp)[i].bad_start; 7680Sstevel@tonic-gate if ((badsec >= (ap->ap_entp)[i].good_start) && 7690Sstevel@tonic-gate (badsec <= ((ap->ap_entp)[i].good_start + numsec))) { 7700Sstevel@tonic-gate fprintf(stderr, "Bad sector %ld is an assigned alternate sector.\n", badsec); 7710Sstevel@tonic-gate exit(66); 7720Sstevel@tonic-gate /* 7730Sstevel@tonic-gate if (!numsec) { 7740Sstevel@tonic-gate (ap->ap_entp)[i].good_start = 0; 7750Sstevel@tonic-gate return(mystatus); 7760Sstevel@tonic-gate } 7770Sstevel@tonic-gate intv[0] = badsec - (ap->ap_entp)[i].good_start; 7780Sstevel@tonic-gate intv[1] = 1; 7790Sstevel@tonic-gate intv[2] = (ap->ap_entp)[i].good_start + numsec - badsec; 7800Sstevel@tonic-gate */ 7810Sstevel@tonic-gate } 7820Sstevel@tonic-gate } 7830Sstevel@tonic-gate /* the bad sector has already been identified as bad */ 7840Sstevel@tonic-gate return(mystatus=SUCCESS); 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate } 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate /* 7900Sstevel@tonic-gate * print_altsec () -- print alternate sector information 7910Sstevel@tonic-gate */ 792*362Sbg159949 int 793*362Sbg159949 print_altsec(struct partition *part) 7940Sstevel@tonic-gate { 7950Sstevel@tonic-gate ap->ap_tblp = NULL; 7960Sstevel@tonic-gate ap->ap_flag &= ~ALTS_ADDPART; 7970Sstevel@tonic-gate read_altsctr(part, 0); 7980Sstevel@tonic-gate print_altsctr(); 7990Sstevel@tonic-gate return(SUCCESS); 8000Sstevel@tonic-gate } 8010Sstevel@tonic-gate 802*362Sbg159949 static void 803*362Sbg159949 print_altsctr(void) 8040Sstevel@tonic-gate { 8050Sstevel@tonic-gate int i; 8060Sstevel@tonic-gate int totalloc; 8070Sstevel@tonic-gate int avail; 8080Sstevel@tonic-gate 8090Sstevel@tonic-gate /* find # of available alternate sectors */ 8100Sstevel@tonic-gate for (i=0, totalloc=0; i<ap->part.p_size; i++) { 8110Sstevel@tonic-gate if ((ap->ap_memmapp)[i]) 8120Sstevel@tonic-gate totalloc++; 8130Sstevel@tonic-gate } 8140Sstevel@tonic-gate /* 8150Sstevel@tonic-gate * available = size of partition - allocated sectors/bad sectors 8160Sstevel@tonic-gate * - partition table - partition map 8170Sstevel@tonic-gate * - entry table 8180Sstevel@tonic-gate */ 8190Sstevel@tonic-gate avail = ap->part.p_size - totalloc; 8200Sstevel@tonic-gate avail = avail - (ap->ap_tbl_secsiz/NBPSCTR) 8210Sstevel@tonic-gate - ap->ap_map_sectot; 8220Sstevel@tonic-gate avail = avail-(ap->ap_tblp->alts_ent_end -ap->ap_tblp->alts_ent_base+1); 8230Sstevel@tonic-gate if (avail < 0) avail = 0; 8240Sstevel@tonic-gate 8250Sstevel@tonic-gate printf("\nALTERNATE SECTOR/TRACK MAPPING TABLE:\n"); 8260Sstevel@tonic-gate printf("\nBad Sector Start\tAlternate Sector Start\t\tCount\n"); 8270Sstevel@tonic-gate 8280Sstevel@tonic-gate for (i=0; i<ap->ap_tblp->alts_ent_used; i++) { 8290Sstevel@tonic-gate printf("\t%ld\t ->\t\t%ld\t\t\t %ld\n", 8300Sstevel@tonic-gate (ap->ap_entp)[i].bad_start, 8310Sstevel@tonic-gate (ap->ap_entp)[i].good_start, 8320Sstevel@tonic-gate ((ap->ap_entp)[i].bad_end - (ap->ap_entp)[i].bad_start + 1)); 8330Sstevel@tonic-gate } 8340Sstevel@tonic-gate printf("\n %ld alternate sector(s) left for allocation.\n", avail); 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate } 8370Sstevel@tonic-gate 838*362Sbg159949 static int 839*362Sbg159949 absdsk_io(int fd, uint srtsec, char *bufp, uint len, int ioflag) 8400Sstevel@tonic-gate { 8410Sstevel@tonic-gate int rc; 8420Sstevel@tonic-gate 8430Sstevel@tonic-gate if (lseek (fd, srtsec * NBPSCTR, SEEK_SET) == -1) 8440Sstevel@tonic-gate return(FAILURE); 8450Sstevel@tonic-gate switch (ioflag) 8460Sstevel@tonic-gate { 8470Sstevel@tonic-gate case CMD_READ: 8480Sstevel@tonic-gate rc = read (fd, bufp, len); 8490Sstevel@tonic-gate break; 8500Sstevel@tonic-gate case CMD_WRITE: 8510Sstevel@tonic-gate rc = write (fd, bufp, len); 8520Sstevel@tonic-gate break; 8530Sstevel@tonic-gate default: 8540Sstevel@tonic-gate break; 8550Sstevel@tonic-gate } 8560Sstevel@tonic-gate if (rc == -1) 8570Sstevel@tonic-gate return(FAILURE); 8580Sstevel@tonic-gate return(SUCCESS); 8590Sstevel@tonic-gate } 860