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
57563SPrasad.Singamsetty@Sun.COM * Common Development and Distribution License (the "License").
67563SPrasad.Singamsetty@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*9889SLarry.Liu@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * This file contains the routines for the IDE drive interface
280Sstevel@tonic-gate */
290Sstevel@tonic-gate #include "global.h"
300Sstevel@tonic-gate
310Sstevel@tonic-gate #include <sys/types.h>
320Sstevel@tonic-gate #include <sys/param.h>
330Sstevel@tonic-gate #include <sys/ioctl.h>
340Sstevel@tonic-gate #include <sys/uio.h>
350Sstevel@tonic-gate #include <sys/fcntl.h>
360Sstevel@tonic-gate #include <memory.h>
370Sstevel@tonic-gate #include <malloc.h>
380Sstevel@tonic-gate #include <unistd.h>
390Sstevel@tonic-gate #include <stdlib.h>
400Sstevel@tonic-gate #include <string.h>
410Sstevel@tonic-gate #include <sys/byteorder.h>
420Sstevel@tonic-gate #include <errno.h>
430Sstevel@tonic-gate #if defined(i386)
440Sstevel@tonic-gate #include <sys/dktp/altsctr.h>
450Sstevel@tonic-gate #endif
460Sstevel@tonic-gate #include <sys/dktp/dadkio.h>
470Sstevel@tonic-gate
480Sstevel@tonic-gate
490Sstevel@tonic-gate #include "startup.h"
500Sstevel@tonic-gate #include "misc.h"
510Sstevel@tonic-gate #include "ctlr_ata.h"
520Sstevel@tonic-gate #include "analyze.h"
530Sstevel@tonic-gate #include "param.h"
540Sstevel@tonic-gate #include "io.h"
550Sstevel@tonic-gate #include "badsec.h"
560Sstevel@tonic-gate
570Sstevel@tonic-gate #include "menu_fdisk.h"
580Sstevel@tonic-gate
590Sstevel@tonic-gate int wr_altsctr();
600Sstevel@tonic-gate int read_altsctr();
610Sstevel@tonic-gate int updatebadsec();
620Sstevel@tonic-gate
630Sstevel@tonic-gate #ifdef __STDC__
640Sstevel@tonic-gate static int ata_ck_format(void);
650Sstevel@tonic-gate #ifdef i386
660Sstevel@tonic-gate static int ata_ex_cur(struct defect_list *);
670Sstevel@tonic-gate static int ata_wr_cur(struct defect_list *);
687563SPrasad.Singamsetty@Sun.COM static int ata_repair(diskaddr_t, int);
690Sstevel@tonic-gate #endif /* i386 */
700Sstevel@tonic-gate #else /* __STDC__ */
710Sstevel@tonic-gate static int ata_ck_format();
720Sstevel@tonic-gate #ifdef i386
730Sstevel@tonic-gate static int ata_ex_cur();
740Sstevel@tonic-gate static int ata_wr_cur();
750Sstevel@tonic-gate static int ata_repair();
760Sstevel@tonic-gate #endif /* i386 */
770Sstevel@tonic-gate #endif
780Sstevel@tonic-gate
790Sstevel@tonic-gate struct ctlr_ops ataops = {
800Sstevel@tonic-gate #if defined(sparc)
810Sstevel@tonic-gate ata_rdwr,
820Sstevel@tonic-gate ata_ck_format,
830Sstevel@tonic-gate 0,
840Sstevel@tonic-gate 0,
850Sstevel@tonic-gate 0,
860Sstevel@tonic-gate 0,
870Sstevel@tonic-gate 0,
880Sstevel@tonic-gate 0,
890Sstevel@tonic-gate #else
900Sstevel@tonic-gate ata_rdwr,
910Sstevel@tonic-gate ata_ck_format,
920Sstevel@tonic-gate 0,
930Sstevel@tonic-gate 0,
940Sstevel@tonic-gate ata_ex_cur,
950Sstevel@tonic-gate ata_repair,
960Sstevel@tonic-gate 0,
970Sstevel@tonic-gate ata_wr_cur,
980Sstevel@tonic-gate #endif /* defined(sparc) */
990Sstevel@tonic-gate };
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate struct ctlr_ops pcmcia_ataops = {
1020Sstevel@tonic-gate ata_rdwr,
1030Sstevel@tonic-gate ata_ck_format,
1040Sstevel@tonic-gate 0,
1050Sstevel@tonic-gate 0,
1060Sstevel@tonic-gate 0,
1070Sstevel@tonic-gate 0,
1080Sstevel@tonic-gate 0,
1090Sstevel@tonic-gate 0,
1100Sstevel@tonic-gate };
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate #if defined(i386)
1147563SPrasad.Singamsetty@Sun.COM static struct dkl_partition *dpart = NULL;
1150Sstevel@tonic-gate #endif /* defined(i386) */
1160Sstevel@tonic-gate extern struct badsec_lst *badsl_chain;
1170Sstevel@tonic-gate extern int badsl_chain_cnt;
1180Sstevel@tonic-gate extern struct badsec_lst *gbadsl_chain;
1190Sstevel@tonic-gate extern int gbadsl_chain_cnt;
1200Sstevel@tonic-gate extern struct alts_mempart *ap;
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate static char *dadkrawioerrs[] = {
1230Sstevel@tonic-gate "cmd was successful", /* DADKIO_STAT_NO_ERROR */
1240Sstevel@tonic-gate "device not ready", /* DADKIO_STAT_NOT_READY */
1250Sstevel@tonic-gate "error on medium blkno: %d", /* DADKIO_STAT_MEDIUM_ERROR */
1260Sstevel@tonic-gate "other hardware error", /* DADKIO_STAT_HARDWARE_ERROR */
1270Sstevel@tonic-gate "illegal request", /* DADKIO_STAT_ILLEGAL_REQUEST */
1280Sstevel@tonic-gate "illegal block address: %d", /* DADKIO_STAT_ILLEGAL_ADDRESS */
1290Sstevel@tonic-gate "device write-protected", /* DADKIO_STAT_WRITE_PROTECTED */
1300Sstevel@tonic-gate "no response from device", /* DADKIO_STAT_TIMED_OUT */
1310Sstevel@tonic-gate "parity error in data", /* DADKIO_STAT_PARITY */
1320Sstevel@tonic-gate "error on bus", /* DADKIO_STAT_BUS_ERROR */
1330Sstevel@tonic-gate "data recovered via ECC", /* DADKIO_STAT_SOFT_ERROR */
1340Sstevel@tonic-gate "no resources for cmd", /* DADKIO_STAT_NO_RESOURCES */
1350Sstevel@tonic-gate "device is not formatted", /* DADKIO_STAT_NOT_FORMATTED */
1360Sstevel@tonic-gate "device is reserved", /* DADKIO_STAT_RESERVED */
1370Sstevel@tonic-gate "feature not supported", /* DADKIO_STAT_NOT_SUPPORTED */
1380Sstevel@tonic-gate };
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate /*ARGSUSED6*/
1410Sstevel@tonic-gate #if defined(i386)
1420Sstevel@tonic-gate int
ata_rdwr(int dir,int fd,diskaddr_t blk64,int secnt,caddr_t bufaddr,int flags,int * xfercntp)1430Sstevel@tonic-gate ata_rdwr(int dir, int fd, diskaddr_t blk64, int secnt, caddr_t bufaddr,
1440Sstevel@tonic-gate int flags, int *xfercntp)
1450Sstevel@tonic-gate #else /* defined(i386) */
1460Sstevel@tonic-gate static int
1470Sstevel@tonic-gate ata_rdwr(int dir, int fd, diskaddr_t blk64, int secnt, caddr_t bufaddr,
1480Sstevel@tonic-gate int flags, int *xfercntp)
1490Sstevel@tonic-gate #endif /* defined(i386) */
1500Sstevel@tonic-gate {
1510Sstevel@tonic-gate int tmpsec;
1520Sstevel@tonic-gate struct dadkio_rwcmd dadkio_rwcmd;
1537563SPrasad.Singamsetty@Sun.COM blkaddr_t blkno;
1540Sstevel@tonic-gate
1557563SPrasad.Singamsetty@Sun.COM blkno = (blkaddr_t)blk64;
1560Sstevel@tonic-gate bzero((caddr_t)&dadkio_rwcmd, sizeof (struct dadkio_rwcmd));
1570Sstevel@tonic-gate
158*9889SLarry.Liu@Sun.COM tmpsec = secnt * cur_blksz;
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate /* Doing raw read */
1610Sstevel@tonic-gate dadkio_rwcmd.cmd = (dir == DIR_READ) ? DADKIO_RWCMD_READ :
1620Sstevel@tonic-gate DADKIO_RWCMD_WRITE;
1630Sstevel@tonic-gate dadkio_rwcmd.blkaddr = blkno;
1640Sstevel@tonic-gate dadkio_rwcmd.buflen = tmpsec;
1650Sstevel@tonic-gate dadkio_rwcmd.flags = flags;
1660Sstevel@tonic-gate dadkio_rwcmd.bufaddr = bufaddr;
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate media_error = 0;
1690Sstevel@tonic-gate if (cur_ctype->ctype_ctype == DKC_PCMCIA_ATA) {
1700Sstevel@tonic-gate /*
1710Sstevel@tonic-gate * PCATA requires to use "p0" when calling
1720Sstevel@tonic-gate * DIOCTL_RWCMD ioctl() to read/write the label
1730Sstevel@tonic-gate */
1740Sstevel@tonic-gate (void) close(fd);
1750Sstevel@tonic-gate (void) open_cur_file(FD_USE_P0_PATH);
1760Sstevel@tonic-gate fd = cur_file;
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate if (ioctl(fd, DIOCTL_RWCMD, &dadkio_rwcmd) == -1) {
1800Sstevel@tonic-gate err_print("DIOCTL_RWCMD: %s\n", strerror(errno));
1810Sstevel@tonic-gate return (1);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate if (cur_ctype->ctype_ctype == DKC_PCMCIA_ATA) {
1850Sstevel@tonic-gate /* Restore cur_file with cur_disk->disk_path */
1860Sstevel@tonic-gate (void) open_cur_file(FD_USE_CUR_DISK_PATH);
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate switch (dadkio_rwcmd.status.status) {
1900Sstevel@tonic-gate case DADKIO_STAT_NOT_READY:
1910Sstevel@tonic-gate disk_error = DISK_STAT_NOTREADY;
1920Sstevel@tonic-gate break;
1930Sstevel@tonic-gate case DADKIO_STAT_RESERVED:
1940Sstevel@tonic-gate disk_error = DISK_STAT_RESERVED;
1950Sstevel@tonic-gate break;
1960Sstevel@tonic-gate case DADKIO_STAT_WRITE_PROTECTED:
1970Sstevel@tonic-gate disk_error = DISK_STAT_DATA_PROTECT;
1980Sstevel@tonic-gate break;
1990Sstevel@tonic-gate case DADKIO_STAT_MEDIUM_ERROR:
2000Sstevel@tonic-gate media_error = 1;
2010Sstevel@tonic-gate break;
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate if (dadkio_rwcmd.status.status) {
2050Sstevel@tonic-gate if ((flags & F_SILENT) == 0)
2060Sstevel@tonic-gate err_print(dadkrawioerrs[dadkio_rwcmd.status.status],
2070Sstevel@tonic-gate dadkio_rwcmd.status.failed_blk);
2080Sstevel@tonic-gate return (1);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate return (0);
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate int
ata_ck_format()2140Sstevel@tonic-gate ata_ck_format()
2150Sstevel@tonic-gate {
216*9889SLarry.Liu@Sun.COM char *bufaddr;
2170Sstevel@tonic-gate int status;
2180Sstevel@tonic-gate
219*9889SLarry.Liu@Sun.COM bufaddr = (char *)zalloc(4 * cur_blksz);
2207563SPrasad.Singamsetty@Sun.COM status = ata_rdwr(DIR_READ, cur_file, (diskaddr_t)1, 4,
2217563SPrasad.Singamsetty@Sun.COM (caddr_t)bufaddr, 0, NULL);
2220Sstevel@tonic-gate
223*9889SLarry.Liu@Sun.COM free(bufaddr);
224*9889SLarry.Liu@Sun.COM
2250Sstevel@tonic-gate return (!status);
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate #if defined(i386)
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate static int
get_alts_slice()2320Sstevel@tonic-gate get_alts_slice()
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate int i;
2360Sstevel@tonic-gate int alts_slice = -1;
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate if (cur_parts == NULL) {
2390Sstevel@tonic-gate (void) fprintf(stderr, "No current partition list\n");
2400Sstevel@tonic-gate return (-1);
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate for (i = 0; i < V_NUMPAR && alts_slice == -1; i++) {
2440Sstevel@tonic-gate if (cur_parts->vtoc.v_part[i].p_tag == V_ALTSCTR) {
2450Sstevel@tonic-gate alts_slice = i;
2467563SPrasad.Singamsetty@Sun.COM dpart = &cur_parts->vtoc.v_part[i];
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate if (alts_slice == -1) {
2510Sstevel@tonic-gate (void) fprintf(stderr, "NO Alt slice\n");
2520Sstevel@tonic-gate return (-1);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate if (!solaris_offset)
2550Sstevel@tonic-gate if (copy_solaris_part(&cur_disk->fdisk_part))
2560Sstevel@tonic-gate return (-1);
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate altsec_offset = dpart->p_start + solaris_offset;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate return (SUCCESS);
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate static int
put_alts_slice()2650Sstevel@tonic-gate put_alts_slice()
2660Sstevel@tonic-gate {
2670Sstevel@tonic-gate int status;
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate status = wr_altsctr();
2700Sstevel@tonic-gate if (status) {
2710Sstevel@tonic-gate return (status);
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate if (ioctl(cur_file, DKIOCADDBAD, NULL) == -1) {
2750Sstevel@tonic-gate (void) fprintf(stderr, "Warning: DKIOCADDBAD ioctl failed\n");
2760Sstevel@tonic-gate sync();
2770Sstevel@tonic-gate return (-1);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate sync();
2800Sstevel@tonic-gate return (0);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate static int
ata_convert_list(struct defect_list * list,int list_format)2840Sstevel@tonic-gate ata_convert_list(struct defect_list *list, int list_format)
2850Sstevel@tonic-gate {
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate int i;
2880Sstevel@tonic-gate struct defect_entry *new_defect;
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate switch (list_format) {
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate case BFI_FORMAT:
2930Sstevel@tonic-gate if (ap->ap_tblp->alts_ent_used) {
2940Sstevel@tonic-gate new_defect = calloc(ap->ap_tblp->alts_ent_used,
2950Sstevel@tonic-gate sizeof (struct defect_entry));
2960Sstevel@tonic-gate if (new_defect == NULL) {
2970Sstevel@tonic-gate err_print(
2980Sstevel@tonic-gate "ata_convert_list: calloc failed\n");
2990Sstevel@tonic-gate fullabort();
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate list->header.count = ap->ap_tblp->alts_ent_used;
3020Sstevel@tonic-gate list->header.magicno = (uint_t)DEFECT_MAGIC;
3030Sstevel@tonic-gate list->list = new_defect;
3040Sstevel@tonic-gate for (i = 0; i < ap->ap_tblp->alts_ent_used;
3057563SPrasad.Singamsetty@Sun.COM i++, new_defect++) {
3060Sstevel@tonic-gate new_defect->cyl =
3077563SPrasad.Singamsetty@Sun.COM bn2c((ap->ap_entp)[i].bad_start);
3080Sstevel@tonic-gate new_defect->head =
3097563SPrasad.Singamsetty@Sun.COM bn2h((ap->ap_entp)[i].bad_start);
3100Sstevel@tonic-gate new_defect->bfi = UNKNOWN;
3110Sstevel@tonic-gate new_defect->sect =
3127563SPrasad.Singamsetty@Sun.COM bn2s((ap->ap_entp)[i].bad_start);
3130Sstevel@tonic-gate new_defect->nbits = UNKNOWN;
3140Sstevel@tonic-gate }
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate } else {
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate list->header.count = 0;
3200Sstevel@tonic-gate list->header.magicno = (uint_t)DEFECT_MAGIC;
3210Sstevel@tonic-gate new_defect = calloc(1,
3220Sstevel@tonic-gate sizeof (struct defect_entry));
3230Sstevel@tonic-gate if (new_defect == NULL) {
3240Sstevel@tonic-gate err_print(
3250Sstevel@tonic-gate "ata_convert_list: calloc failed\n");
3260Sstevel@tonic-gate fullabort();
3270Sstevel@tonic-gate }
3280Sstevel@tonic-gate list->list = new_defect;
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate break;
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate default:
3330Sstevel@tonic-gate err_print("ata_convert_list: can't deal with it\n");
3340Sstevel@tonic-gate exit(0);
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate (void) checkdefsum(list, CK_MAKESUM);
3370Sstevel@tonic-gate return (0);
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate /*
3420Sstevel@tonic-gate * NB - there used to be a ata_ex_man() which was identical to
3430Sstevel@tonic-gate * ata_ex_cur; since it's really not a "manufacturer's list",
3440Sstevel@tonic-gate * it's gone; if we ever want that exact functionality back,
3450Sstevel@tonic-gate * we can add ata_ex_cur() to the ctlr_ops above. Otherwise,
3460Sstevel@tonic-gate * if this is ever modified to support formatting of IDE drives,
3470Sstevel@tonic-gate * we should probably add something that issues the
3480Sstevel@tonic-gate * drive Read Defect list rather than getting the s9 info
3490Sstevel@tonic-gate * as ata_ex_cur() does.
3500Sstevel@tonic-gate */
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate static int
ata_ex_cur(struct defect_list * list)3530Sstevel@tonic-gate ata_ex_cur(struct defect_list *list)
3540Sstevel@tonic-gate {
3550Sstevel@tonic-gate int status;
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate status = get_alts_slice();
3580Sstevel@tonic-gate if (status)
3590Sstevel@tonic-gate return (status);
3600Sstevel@tonic-gate status = read_altsctr(dpart);
3610Sstevel@tonic-gate if (status) {
3620Sstevel@tonic-gate return (status);
3630Sstevel@tonic-gate }
3640Sstevel@tonic-gate (void) ata_convert_list(list, BFI_FORMAT);
3650Sstevel@tonic-gate return (status);
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate
3680Sstevel@tonic-gate int
ata_repair(diskaddr_t bn,int flag)3697563SPrasad.Singamsetty@Sun.COM ata_repair(diskaddr_t bn, int flag)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate
3720Sstevel@tonic-gate int status;
3730Sstevel@tonic-gate struct badsec_lst *blc_p;
3740Sstevel@tonic-gate struct badsec_lst *blc_p_nxt;
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate #ifdef lint
3770Sstevel@tonic-gate flag++;
3780Sstevel@tonic-gate #endif
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate (void) get_alts_slice();
3810Sstevel@tonic-gate if (!gbadsl_chain) {
3820Sstevel@tonic-gate blc_p = (struct badsec_lst *)calloc(1, BADSLSZ);
3830Sstevel@tonic-gate if (!blc_p) {
3840Sstevel@tonic-gate (void) fprintf(stderr,
3850Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n");
3860Sstevel@tonic-gate return (-1);
3870Sstevel@tonic-gate }
3880Sstevel@tonic-gate gbadsl_chain = blc_p;
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p->bl_nxt; )
3910Sstevel@tonic-gate blc_p = blc_p->bl_nxt;
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate if (blc_p->bl_cnt == MAXBLENT) {
3940Sstevel@tonic-gate blc_p->bl_nxt = (struct badsec_lst *)calloc(1, BADSLSZ);
3950Sstevel@tonic-gate if (!blc_p->bl_nxt) {
3960Sstevel@tonic-gate (void) fprintf(stderr,
3970Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n");
3980Sstevel@tonic-gate return (-1);
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate blc_p = blc_p->bl_nxt;
4010Sstevel@tonic-gate }
4027563SPrasad.Singamsetty@Sun.COM blc_p->bl_sec[blc_p->bl_cnt++] = (uint_t)bn;
4030Sstevel@tonic-gate gbadsl_chain_cnt++;
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate (void) updatebadsec(dpart, 0);
4060Sstevel@tonic-gate status = put_alts_slice();
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate /* clear out the bad sector list chains that were generated */
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate if (badsl_chain) {
4110Sstevel@tonic-gate if (badsl_chain->bl_nxt == NULL) {
4120Sstevel@tonic-gate free(badsl_chain);
4130Sstevel@tonic-gate } else {
4140Sstevel@tonic-gate for (blc_p = badsl_chain; blc_p; ) {
4150Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt;
4160Sstevel@tonic-gate free(blc_p);
4170Sstevel@tonic-gate blc_p = blc_p_nxt;
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate badsl_chain = NULL;
4210Sstevel@tonic-gate badsl_chain_cnt = 0;
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate
4240Sstevel@tonic-gate if (gbadsl_chain) {
4250Sstevel@tonic-gate if (gbadsl_chain->bl_nxt == NULL) {
4260Sstevel@tonic-gate free(gbadsl_chain);
4270Sstevel@tonic-gate } else {
4280Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p; ) {
4290Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt;
4300Sstevel@tonic-gate free(blc_p);
4310Sstevel@tonic-gate blc_p = blc_p_nxt;
4320Sstevel@tonic-gate }
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate gbadsl_chain = NULL;
4350Sstevel@tonic-gate gbadsl_chain_cnt = 0;
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate
4380Sstevel@tonic-gate return (status);
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate int
ata_wr_cur(struct defect_list * list)4430Sstevel@tonic-gate ata_wr_cur(struct defect_list *list)
4440Sstevel@tonic-gate {
4450Sstevel@tonic-gate int status;
4460Sstevel@tonic-gate int sec_count;
4470Sstevel@tonic-gate int x;
4480Sstevel@tonic-gate struct badsec_lst *blc_p;
4490Sstevel@tonic-gate struct badsec_lst *blc_p_nxt;
4500Sstevel@tonic-gate struct defect_entry *dlist;
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate if (list->header.magicno != (uint_t)DEFECT_MAGIC)
4530Sstevel@tonic-gate return (-1);
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate sec_count = list->header.count;
4560Sstevel@tonic-gate dlist = list->list;
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate (void) get_alts_slice();
4590Sstevel@tonic-gate for (x = 0; x < sec_count; x++) {
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate /* test for unsupported list format */
4620Sstevel@tonic-gate if ((dlist->bfi != UNKNOWN) || (dlist->nbits != UNKNOWN)) {
4630Sstevel@tonic-gate (void) fprintf(stderr,
4647563SPrasad.Singamsetty@Sun.COM "BFI unsuported format for bad sectors\n");
4650Sstevel@tonic-gate return (-1);
4660Sstevel@tonic-gate }
4670Sstevel@tonic-gate
4680Sstevel@tonic-gate if (!gbadsl_chain) {
4690Sstevel@tonic-gate blc_p = (struct badsec_lst *)calloc(1, BADSLSZ);
4700Sstevel@tonic-gate if (!blc_p) {
4710Sstevel@tonic-gate (void) fprintf(stderr,
4720Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n");
4730Sstevel@tonic-gate return (-1);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate gbadsl_chain = blc_p;
4760Sstevel@tonic-gate }
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p->bl_nxt; )
4790Sstevel@tonic-gate blc_p = blc_p->bl_nxt;
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate if (blc_p->bl_cnt == MAXBLENT) {
4820Sstevel@tonic-gate blc_p->bl_nxt = (struct badsec_lst *)calloc(1, BADSLSZ);
4830Sstevel@tonic-gate if (!blc_p->bl_nxt) {
4840Sstevel@tonic-gate (void) fprintf(stderr,
4850Sstevel@tonic-gate "Unable to allocate memory for additional bad sectors\n");
4860Sstevel@tonic-gate return (-1);
4870Sstevel@tonic-gate }
4880Sstevel@tonic-gate blc_p = blc_p->bl_nxt;
4890Sstevel@tonic-gate }
4900Sstevel@tonic-gate blc_p->bl_sec[blc_p->bl_cnt++] =
4917563SPrasad.Singamsetty@Sun.COM (uint_t)chs2bn(dlist->cyl, dlist->head, dlist->sect);
4920Sstevel@tonic-gate gbadsl_chain_cnt++;
4930Sstevel@tonic-gate dlist++;
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate (void) updatebadsec(dpart, 0);
4980Sstevel@tonic-gate status = put_alts_slice();
4990Sstevel@tonic-gate
5000Sstevel@tonic-gate /* clear out the bad sector list chains that were generated */
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate if (badsl_chain) {
5030Sstevel@tonic-gate if (badsl_chain->bl_nxt == NULL) {
5040Sstevel@tonic-gate free(badsl_chain);
5050Sstevel@tonic-gate } else {
5060Sstevel@tonic-gate for (blc_p = badsl_chain; blc_p; ) {
5070Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt;
5080Sstevel@tonic-gate free(blc_p);
5090Sstevel@tonic-gate blc_p = blc_p_nxt;
5100Sstevel@tonic-gate }
5110Sstevel@tonic-gate }
5120Sstevel@tonic-gate badsl_chain = NULL;
5130Sstevel@tonic-gate badsl_chain_cnt = 0;
5140Sstevel@tonic-gate }
5150Sstevel@tonic-gate
5160Sstevel@tonic-gate if (gbadsl_chain) {
5170Sstevel@tonic-gate if (gbadsl_chain->bl_nxt == NULL) {
5180Sstevel@tonic-gate free(gbadsl_chain);
5190Sstevel@tonic-gate } else {
5200Sstevel@tonic-gate for (blc_p = gbadsl_chain; blc_p; ) {
5210Sstevel@tonic-gate blc_p_nxt = blc_p->bl_nxt;
5220Sstevel@tonic-gate free(blc_p);
5230Sstevel@tonic-gate blc_p = blc_p_nxt;
5240Sstevel@tonic-gate }
5250Sstevel@tonic-gate }
5260Sstevel@tonic-gate gbadsl_chain = NULL;
5270Sstevel@tonic-gate gbadsl_chain_cnt = 0;
5280Sstevel@tonic-gate }
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate return (status);
5310Sstevel@tonic-gate }
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate #endif /* defined(i386) */
534