17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5342440ecSPrasad Singamsetty * Common Development and Distribution License (the "License"). 6342440ecSPrasad Singamsetty * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*65908c77Syu, larry liu - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * This file contains the routines for the IDE drive interface 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate #include "global.h" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/param.h> 337c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 347c478bd9Sstevel@tonic-gate #include <sys/uio.h> 357c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 367c478bd9Sstevel@tonic-gate #include <memory.h> 377c478bd9Sstevel@tonic-gate #include <malloc.h> 387c478bd9Sstevel@tonic-gate #include <unistd.h> 397c478bd9Sstevel@tonic-gate #include <stdlib.h> 407c478bd9Sstevel@tonic-gate #include <string.h> 417c478bd9Sstevel@tonic-gate #include <sys/byteorder.h> 427c478bd9Sstevel@tonic-gate #include <errno.h> 437c478bd9Sstevel@tonic-gate #if defined(i386) 447c478bd9Sstevel@tonic-gate #include <sys/dktp/altsctr.h> 457c478bd9Sstevel@tonic-gate #endif 467c478bd9Sstevel@tonic-gate #include <sys/dktp/dadkio.h> 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include "startup.h" 507c478bd9Sstevel@tonic-gate #include "misc.h" 517c478bd9Sstevel@tonic-gate #include "ctlr_ata.h" 527c478bd9Sstevel@tonic-gate #include "analyze.h" 537c478bd9Sstevel@tonic-gate #include "param.h" 547c478bd9Sstevel@tonic-gate #include "io.h" 557c478bd9Sstevel@tonic-gate #include "badsec.h" 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate #include "menu_fdisk.h" 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate int wr_altsctr(); 607c478bd9Sstevel@tonic-gate int read_altsctr(); 617c478bd9Sstevel@tonic-gate int updatebadsec(); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate #ifdef __STDC__ 647c478bd9Sstevel@tonic-gate static int ata_ck_format(void); 657c478bd9Sstevel@tonic-gate #ifdef i386 667c478bd9Sstevel@tonic-gate static int ata_ex_cur(struct defect_list *); 677c478bd9Sstevel@tonic-gate static int ata_wr_cur(struct defect_list *); 68342440ecSPrasad Singamsetty static int ata_repair(diskaddr_t, int); 697c478bd9Sstevel@tonic-gate #endif /* i386 */ 707c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 717c478bd9Sstevel@tonic-gate static int ata_ck_format(); 727c478bd9Sstevel@tonic-gate #ifdef i386 737c478bd9Sstevel@tonic-gate static int ata_ex_cur(); 747c478bd9Sstevel@tonic-gate static int ata_wr_cur(); 757c478bd9Sstevel@tonic-gate static int ata_repair(); 767c478bd9Sstevel@tonic-gate #endif /* i386 */ 777c478bd9Sstevel@tonic-gate #endif 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate struct ctlr_ops ataops = { 807c478bd9Sstevel@tonic-gate #if defined(sparc) 817c478bd9Sstevel@tonic-gate ata_rdwr, 827c478bd9Sstevel@tonic-gate ata_ck_format, 837c478bd9Sstevel@tonic-gate 0, 847c478bd9Sstevel@tonic-gate 0, 857c478bd9Sstevel@tonic-gate 0, 867c478bd9Sstevel@tonic-gate 0, 877c478bd9Sstevel@tonic-gate 0, 887c478bd9Sstevel@tonic-gate 0, 897c478bd9Sstevel@tonic-gate #else 907c478bd9Sstevel@tonic-gate ata_rdwr, 917c478bd9Sstevel@tonic-gate ata_ck_format, 927c478bd9Sstevel@tonic-gate 0, 937c478bd9Sstevel@tonic-gate 0, 947c478bd9Sstevel@tonic-gate ata_ex_cur, 957c478bd9Sstevel@tonic-gate ata_repair, 967c478bd9Sstevel@tonic-gate 0, 977c478bd9Sstevel@tonic-gate ata_wr_cur, 987c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 997c478bd9Sstevel@tonic-gate }; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate struct ctlr_ops pcmcia_ataops = { 1027c478bd9Sstevel@tonic-gate ata_rdwr, 1037c478bd9Sstevel@tonic-gate ata_ck_format, 1047c478bd9Sstevel@tonic-gate 0, 1057c478bd9Sstevel@tonic-gate 0, 1067c478bd9Sstevel@tonic-gate 0, 1077c478bd9Sstevel@tonic-gate 0, 1087c478bd9Sstevel@tonic-gate 0, 1097c478bd9Sstevel@tonic-gate 0, 1107c478bd9Sstevel@tonic-gate }; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate #if defined(i386) 114342440ecSPrasad Singamsetty static struct dkl_partition *dpart = NULL; 1157c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 1167c478bd9Sstevel@tonic-gate extern struct badsec_lst *badsl_chain; 1177c478bd9Sstevel@tonic-gate extern int badsl_chain_cnt; 1187c478bd9Sstevel@tonic-gate extern struct badsec_lst *gbadsl_chain; 1197c478bd9Sstevel@tonic-gate extern int gbadsl_chain_cnt; 1207c478bd9Sstevel@tonic-gate extern struct alts_mempart *ap; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate static char *dadkrawioerrs[] = { 1237c478bd9Sstevel@tonic-gate "cmd was successful", /* DADKIO_STAT_NO_ERROR */ 1247c478bd9Sstevel@tonic-gate "device not ready", /* DADKIO_STAT_NOT_READY */ 1257c478bd9Sstevel@tonic-gate "error on medium blkno: %d", /* DADKIO_STAT_MEDIUM_ERROR */ 1267c478bd9Sstevel@tonic-gate "other hardware error", /* DADKIO_STAT_HARDWARE_ERROR */ 1277c478bd9Sstevel@tonic-gate "illegal request", /* DADKIO_STAT_ILLEGAL_REQUEST */ 1287c478bd9Sstevel@tonic-gate "illegal block address: %d", /* DADKIO_STAT_ILLEGAL_ADDRESS */ 1297c478bd9Sstevel@tonic-gate "device write-protected", /* DADKIO_STAT_WRITE_PROTECTED */ 1307c478bd9Sstevel@tonic-gate "no response from device", /* DADKIO_STAT_TIMED_OUT */ 1317c478bd9Sstevel@tonic-gate "parity error in data", /* DADKIO_STAT_PARITY */ 1327c478bd9Sstevel@tonic-gate "error on bus", /* DADKIO_STAT_BUS_ERROR */ 1337c478bd9Sstevel@tonic-gate "data recovered via ECC", /* DADKIO_STAT_SOFT_ERROR */ 1347c478bd9Sstevel@tonic-gate "no resources for cmd", /* DADKIO_STAT_NO_RESOURCES */ 1357c478bd9Sstevel@tonic-gate "device is not formatted", /* DADKIO_STAT_NOT_FORMATTED */ 1367c478bd9Sstevel@tonic-gate "device is reserved", /* DADKIO_STAT_RESERVED */ 1377c478bd9Sstevel@tonic-gate "feature not supported", /* DADKIO_STAT_NOT_SUPPORTED */ 1387c478bd9Sstevel@tonic-gate }; 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /*ARGSUSED6*/ 1417c478bd9Sstevel@tonic-gate #if defined(i386) 1427c478bd9Sstevel@tonic-gate int 1437c478bd9Sstevel@tonic-gate ata_rdwr(int dir, int fd, diskaddr_t blk64, int secnt, caddr_t bufaddr, 1447c478bd9Sstevel@tonic-gate int flags, int *xfercntp) 1457c478bd9Sstevel@tonic-gate #else /* defined(i386) */ 1467c478bd9Sstevel@tonic-gate static int 1477c478bd9Sstevel@tonic-gate ata_rdwr(int dir, int fd, diskaddr_t blk64, int secnt, caddr_t bufaddr, 1487c478bd9Sstevel@tonic-gate int flags, int *xfercntp) 1497c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 1507c478bd9Sstevel@tonic-gate { 1517c478bd9Sstevel@tonic-gate int tmpsec; 1527c478bd9Sstevel@tonic-gate struct dadkio_rwcmd dadkio_rwcmd; 153342440ecSPrasad Singamsetty blkaddr_t blkno; 1547c478bd9Sstevel@tonic-gate 155342440ecSPrasad Singamsetty blkno = (blkaddr_t)blk64; 1567c478bd9Sstevel@tonic-gate bzero((caddr_t)&dadkio_rwcmd, sizeof (struct dadkio_rwcmd)); 1577c478bd9Sstevel@tonic-gate 158*65908c77Syu, larry liu - Sun Microsystems - Beijing China tmpsec = secnt * cur_blksz; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate /* Doing raw read */ 1617c478bd9Sstevel@tonic-gate dadkio_rwcmd.cmd = (dir == DIR_READ) ? DADKIO_RWCMD_READ : 1627c478bd9Sstevel@tonic-gate DADKIO_RWCMD_WRITE; 1637c478bd9Sstevel@tonic-gate dadkio_rwcmd.blkaddr = blkno; 1647c478bd9Sstevel@tonic-gate dadkio_rwcmd.buflen = tmpsec; 1657c478bd9Sstevel@tonic-gate dadkio_rwcmd.flags = flags; 1667c478bd9Sstevel@tonic-gate dadkio_rwcmd.bufaddr = bufaddr; 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate media_error = 0; 1697c478bd9Sstevel@tonic-gate if (cur_ctype->ctype_ctype == DKC_PCMCIA_ATA) { 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * PCATA requires to use "p0" when calling 1727c478bd9Sstevel@tonic-gate * DIOCTL_RWCMD ioctl() to read/write the label 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate (void) close(fd); 1757c478bd9Sstevel@tonic-gate (void) open_cur_file(FD_USE_P0_PATH); 1767c478bd9Sstevel@tonic-gate fd = cur_file; 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate if (ioctl(fd, DIOCTL_RWCMD, &dadkio_rwcmd) == -1) { 1807c478bd9Sstevel@tonic-gate err_print("DIOCTL_RWCMD: %s\n", strerror(errno)); 1817c478bd9Sstevel@tonic-gate return (1); 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (cur_ctype->ctype_ctype == DKC_PCMCIA_ATA) { 1857c478bd9Sstevel@tonic-gate /* Restore cur_file with cur_disk->disk_path */ 1867c478bd9Sstevel@tonic-gate (void) open_cur_file(FD_USE_CUR_DISK_PATH); 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate switch (dadkio_rwcmd.status.status) { 1907c478bd9Sstevel@tonic-gate case DADKIO_STAT_NOT_READY: 1917c478bd9Sstevel@tonic-gate disk_error = DISK_STAT_NOTREADY; 1927c478bd9Sstevel@tonic-gate break; 1937c478bd9Sstevel@tonic-gate case DADKIO_STAT_RESERVED: 1947c478bd9Sstevel@tonic-gate disk_error = DISK_STAT_RESERVED; 1957c478bd9Sstevel@tonic-gate break; 1967c478bd9Sstevel@tonic-gate case DADKIO_STAT_WRITE_PROTECTED: 1977c478bd9Sstevel@tonic-gate disk_error = DISK_STAT_DATA_PROTECT; 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate case DADKIO_STAT_MEDIUM_ERROR: 2007c478bd9Sstevel@tonic-gate media_error = 1; 2017c478bd9Sstevel@tonic-gate break; 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate if (dadkio_rwcmd.status.status) { 2057c478bd9Sstevel@tonic-gate if ((flags & F_SILENT) == 0) 2067c478bd9Sstevel@tonic-gate err_print(dadkrawioerrs[dadkio_rwcmd.status.status], 2077c478bd9Sstevel@tonic-gate dadkio_rwcmd.status.failed_blk); 2087c478bd9Sstevel@tonic-gate return (1); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate return (0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate int 2147c478bd9Sstevel@tonic-gate ata_ck_format() 2157c478bd9Sstevel@tonic-gate { 216*65908c77Syu, larry liu - Sun Microsystems - Beijing China char *bufaddr; 2177c478bd9Sstevel@tonic-gate int status; 2187c478bd9Sstevel@tonic-gate 219*65908c77Syu, larry liu - Sun Microsystems - Beijing China bufaddr = (char *)zalloc(4 * cur_blksz); 220342440ecSPrasad Singamsetty status = ata_rdwr(DIR_READ, cur_file, (diskaddr_t)1, 4, 221342440ecSPrasad Singamsetty (caddr_t)bufaddr, 0, NULL); 2227c478bd9Sstevel@tonic-gate 223*65908c77Syu, larry liu - Sun Microsystems - Beijing China free(bufaddr); 224*65908c77Syu, larry liu - Sun Microsystems - Beijing China 2257c478bd9Sstevel@tonic-gate return (!status); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate #if defined(i386) 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate static int 2327c478bd9Sstevel@tonic-gate get_alts_slice() 2337c478bd9Sstevel@tonic-gate { 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate int i; 2367c478bd9Sstevel@tonic-gate int alts_slice = -1; 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if (cur_parts == NULL) { 2397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "No current partition list\n"); 2407c478bd9Sstevel@tonic-gate return (-1); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR && alts_slice == -1; i++) { 2447c478bd9Sstevel@tonic-gate if (cur_parts->vtoc.v_part[i].p_tag == V_ALTSCTR) { 2457c478bd9Sstevel@tonic-gate alts_slice = i; 246342440ecSPrasad Singamsetty dpart = &cur_parts->vtoc.v_part[i]; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate if (alts_slice == -1) { 2517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "NO Alt slice\n"); 2527c478bd9Sstevel@tonic-gate return (-1); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate if (!solaris_offset) 2557c478bd9Sstevel@tonic-gate if (copy_solaris_part(&cur_disk->fdisk_part)) 2567c478bd9Sstevel@tonic-gate return (-1); 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate altsec_offset = dpart->p_start + solaris_offset; 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate return (SUCCESS); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate static int 2657c478bd9Sstevel@tonic-gate put_alts_slice() 2667c478bd9Sstevel@tonic-gate { 2677c478bd9Sstevel@tonic-gate int status; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate status = wr_altsctr(); 2707c478bd9Sstevel@tonic-gate if (status) { 2717c478bd9Sstevel@tonic-gate return (status); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (ioctl(cur_file, DKIOCADDBAD, NULL) == -1) { 2757c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Warning: DKIOCADDBAD ioctl failed\n"); 2767c478bd9Sstevel@tonic-gate sync(); 2777c478bd9Sstevel@tonic-gate return (-1); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate sync(); 2807c478bd9Sstevel@tonic-gate return (0); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate static int 2847c478bd9Sstevel@tonic-gate ata_convert_list(struct defect_list *list, int list_format) 2857c478bd9Sstevel@tonic-gate { 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate int i; 2887c478bd9Sstevel@tonic-gate struct defect_entry *new_defect; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate switch (list_format) { 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate case BFI_FORMAT: 2937c478bd9Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_used) { 2947c478bd9Sstevel@tonic-gate new_defect = calloc(ap->ap_tblp->alts_ent_used, 2957c478bd9Sstevel@tonic-gate sizeof (struct defect_entry)); 2967c478bd9Sstevel@tonic-gate if (new_defect == NULL) { 2977c478bd9Sstevel@tonic-gate err_print( 2987c478bd9Sstevel@tonic-gate "ata_convert_list: calloc failed\n"); 2997c478bd9Sstevel@tonic-gate fullabort(); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate list->header.count = ap->ap_tblp->alts_ent_used; 3027c478bd9Sstevel@tonic-gate list->header.magicno = (uint_t)DEFECT_MAGIC; 3037c478bd9Sstevel@tonic-gate list->list = new_defect; 3047c478bd9Sstevel@tonic-gate for (i = 0; i < ap->ap_tblp->alts_ent_used; 3057c478bd9Sstevel@tonic-gate i++, new_defect++) { 3067c478bd9Sstevel@tonic-gate new_defect->cyl = 3077c478bd9Sstevel@tonic-gate bn2c((ap->ap_entp)[i].bad_start); 3087c478bd9Sstevel@tonic-gate new_defect->head = 3097c478bd9Sstevel@tonic-gate bn2h((ap->ap_entp)[i].bad_start); 3107c478bd9Sstevel@tonic-gate new_defect->bfi = UNKNOWN; 3117c478bd9Sstevel@tonic-gate new_defect->sect = 3127c478bd9Sstevel@tonic-gate bn2s((ap->ap_entp)[i].bad_start); 3137c478bd9Sstevel@tonic-gate new_defect->nbits = UNKNOWN; 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate } else { 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate list->header.count = 0; 3207c478bd9Sstevel@tonic-gate list->header.magicno = (uint_t)DEFECT_MAGIC; 3217c478bd9Sstevel@tonic-gate new_defect = calloc(1, 3227c478bd9Sstevel@tonic-gate sizeof (struct defect_entry)); 3237c478bd9Sstevel@tonic-gate if (new_defect == NULL) { 3247c478bd9Sstevel@tonic-gate err_print( 3257c478bd9Sstevel@tonic-gate "ata_convert_list: calloc failed\n"); 3267c478bd9Sstevel@tonic-gate fullabort(); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate list->list = new_defect; 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate break; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate default: 3337c478bd9Sstevel@tonic-gate err_print("ata_convert_list: can't deal with it\n"); 3347c478bd9Sstevel@tonic-gate exit(0); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate (void) checkdefsum(list, CK_MAKESUM); 3377c478bd9Sstevel@tonic-gate return (0); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate /* 3427c478bd9Sstevel@tonic-gate * NB - there used to be a ata_ex_man() which was identical to 3437c478bd9Sstevel@tonic-gate * ata_ex_cur; since it's really not a "manufacturer's list", 3447c478bd9Sstevel@tonic-gate * it's gone; if we ever want that exact functionality back, 3457c478bd9Sstevel@tonic-gate * we can add ata_ex_cur() to the ctlr_ops above. Otherwise, 3467c478bd9Sstevel@tonic-gate * if this is ever modified to support formatting of IDE drives, 3477c478bd9Sstevel@tonic-gate * we should probably add something that issues the 3487c478bd9Sstevel@tonic-gate * drive Read Defect list rather than getting the s9 info 3497c478bd9Sstevel@tonic-gate * as ata_ex_cur() does. 3507c478bd9Sstevel@tonic-gate */ 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate static int 3537c478bd9Sstevel@tonic-gate ata_ex_cur(struct defect_list *list) 3547c478bd9Sstevel@tonic-gate { 3557c478bd9Sstevel@tonic-gate int status; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate status = get_alts_slice(); 3587c478bd9Sstevel@tonic-gate if (status) 3597c478bd9Sstevel@tonic-gate return (status); 3607c478bd9Sstevel@tonic-gate status = read_altsctr(dpart); 3617c478bd9Sstevel@tonic-gate if (status) { 3627c478bd9Sstevel@tonic-gate return (status); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate (void) ata_convert_list(list, BFI_FORMAT); 3657c478bd9Sstevel@tonic-gate return (status); 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate int 369342440ecSPrasad Singamsetty ata_repair(diskaddr_t bn, int flag) 3707c478bd9Sstevel@tonic-gate { 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate int status; 3737c478bd9Sstevel@tonic-gate struct badsec_lst *blc_p; 3747c478bd9Sstevel@tonic-gate struct badsec_lst *blc_p_nxt; 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate #ifdef lint 3777c478bd9Sstevel@tonic-gate flag++; 3787c478bd9Sstevel@tonic-gate #endif 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate (void) get_alts_slice(); 3817c478bd9Sstevel@tonic-gate if (!gbadsl_chain) { 3827c478bd9Sstevel@tonic-gate blc_p = (struct badsec_lst *)calloc(1, BADSLSZ); 3837c478bd9Sstevel@tonic-gate if (!blc_p) { 3847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3857c478bd9Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n"); 3867c478bd9Sstevel@tonic-gate return (-1); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate gbadsl_chain = blc_p; 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p->bl_nxt; ) 3917c478bd9Sstevel@tonic-gate blc_p = blc_p->bl_nxt; 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate if (blc_p->bl_cnt == MAXBLENT) { 3947c478bd9Sstevel@tonic-gate blc_p->bl_nxt = (struct badsec_lst *)calloc(1, BADSLSZ); 3957c478bd9Sstevel@tonic-gate if (!blc_p->bl_nxt) { 3967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3977c478bd9Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n"); 3987c478bd9Sstevel@tonic-gate return (-1); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate blc_p = blc_p->bl_nxt; 4017c478bd9Sstevel@tonic-gate } 402342440ecSPrasad Singamsetty blc_p->bl_sec[blc_p->bl_cnt++] = (uint_t)bn; 4037c478bd9Sstevel@tonic-gate gbadsl_chain_cnt++; 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate (void) updatebadsec(dpart, 0); 4067c478bd9Sstevel@tonic-gate status = put_alts_slice(); 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate /* clear out the bad sector list chains that were generated */ 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate if (badsl_chain) { 4117c478bd9Sstevel@tonic-gate if (badsl_chain->bl_nxt == NULL) { 4127c478bd9Sstevel@tonic-gate free(badsl_chain); 4137c478bd9Sstevel@tonic-gate } else { 4147c478bd9Sstevel@tonic-gate for (blc_p = badsl_chain; blc_p; ) { 4157c478bd9Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt; 4167c478bd9Sstevel@tonic-gate free(blc_p); 4177c478bd9Sstevel@tonic-gate blc_p = blc_p_nxt; 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate badsl_chain = NULL; 4217c478bd9Sstevel@tonic-gate badsl_chain_cnt = 0; 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate if (gbadsl_chain) { 4257c478bd9Sstevel@tonic-gate if (gbadsl_chain->bl_nxt == NULL) { 4267c478bd9Sstevel@tonic-gate free(gbadsl_chain); 4277c478bd9Sstevel@tonic-gate } else { 4287c478bd9Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p; ) { 4297c478bd9Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt; 4307c478bd9Sstevel@tonic-gate free(blc_p); 4317c478bd9Sstevel@tonic-gate blc_p = blc_p_nxt; 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate } 4347c478bd9Sstevel@tonic-gate gbadsl_chain = NULL; 4357c478bd9Sstevel@tonic-gate gbadsl_chain_cnt = 0; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate return (status); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate int 4437c478bd9Sstevel@tonic-gate ata_wr_cur(struct defect_list *list) 4447c478bd9Sstevel@tonic-gate { 4457c478bd9Sstevel@tonic-gate int status; 4467c478bd9Sstevel@tonic-gate int sec_count; 4477c478bd9Sstevel@tonic-gate int x; 4487c478bd9Sstevel@tonic-gate struct badsec_lst *blc_p; 4497c478bd9Sstevel@tonic-gate struct badsec_lst *blc_p_nxt; 4507c478bd9Sstevel@tonic-gate struct defect_entry *dlist; 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if (list->header.magicno != (uint_t)DEFECT_MAGIC) 4537c478bd9Sstevel@tonic-gate return (-1); 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate sec_count = list->header.count; 4567c478bd9Sstevel@tonic-gate dlist = list->list; 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate (void) get_alts_slice(); 4597c478bd9Sstevel@tonic-gate for (x = 0; x < sec_count; x++) { 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate /* test for unsupported list format */ 4627c478bd9Sstevel@tonic-gate if ((dlist->bfi != UNKNOWN) || (dlist->nbits != UNKNOWN)) { 4637c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4647c478bd9Sstevel@tonic-gate "BFI unsuported format for bad sectors\n"); 4657c478bd9Sstevel@tonic-gate return (-1); 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate if (!gbadsl_chain) { 4697c478bd9Sstevel@tonic-gate blc_p = (struct badsec_lst *)calloc(1, BADSLSZ); 4707c478bd9Sstevel@tonic-gate if (!blc_p) { 4717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4727c478bd9Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n"); 4737c478bd9Sstevel@tonic-gate return (-1); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate gbadsl_chain = blc_p; 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p->bl_nxt; ) 4797c478bd9Sstevel@tonic-gate blc_p = blc_p->bl_nxt; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if (blc_p->bl_cnt == MAXBLENT) { 4827c478bd9Sstevel@tonic-gate blc_p->bl_nxt = (struct badsec_lst *)calloc(1, BADSLSZ); 4837c478bd9Sstevel@tonic-gate if (!blc_p->bl_nxt) { 4847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4857c478bd9Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n"); 4867c478bd9Sstevel@tonic-gate return (-1); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate blc_p = blc_p->bl_nxt; 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate blc_p->bl_sec[blc_p->bl_cnt++] = 491342440ecSPrasad Singamsetty (uint_t)chs2bn(dlist->cyl, dlist->head, dlist->sect); 4927c478bd9Sstevel@tonic-gate gbadsl_chain_cnt++; 4937c478bd9Sstevel@tonic-gate dlist++; 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate (void) updatebadsec(dpart, 0); 4987c478bd9Sstevel@tonic-gate status = put_alts_slice(); 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* clear out the bad sector list chains that were generated */ 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate if (badsl_chain) { 5037c478bd9Sstevel@tonic-gate if (badsl_chain->bl_nxt == NULL) { 5047c478bd9Sstevel@tonic-gate free(badsl_chain); 5057c478bd9Sstevel@tonic-gate } else { 5067c478bd9Sstevel@tonic-gate for (blc_p = badsl_chain; blc_p; ) { 5077c478bd9Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt; 5087c478bd9Sstevel@tonic-gate free(blc_p); 5097c478bd9Sstevel@tonic-gate blc_p = blc_p_nxt; 5107c478bd9Sstevel@tonic-gate } 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate badsl_chain = NULL; 5137c478bd9Sstevel@tonic-gate badsl_chain_cnt = 0; 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate if (gbadsl_chain) { 5177c478bd9Sstevel@tonic-gate if (gbadsl_chain->bl_nxt == NULL) { 5187c478bd9Sstevel@tonic-gate free(gbadsl_chain); 5197c478bd9Sstevel@tonic-gate } else { 5207c478bd9Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p; ) { 5217c478bd9Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt; 5227c478bd9Sstevel@tonic-gate free(blc_p); 5237c478bd9Sstevel@tonic-gate blc_p = blc_p_nxt; 5247c478bd9Sstevel@tonic-gate } 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate gbadsl_chain = NULL; 5277c478bd9Sstevel@tonic-gate gbadsl_chain_cnt = 0; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate return (status); 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate #endif /* defined(i386) */ 534