xref: /onnv-gate/usr/src/cmd/format/main.c (revision 9889:68d0fe4c716e)
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
51564Slh195018  * Common Development and Distribution License (the "License").
61564Slh195018  * 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 main entry point of the program and other
280Sstevel@tonic-gate  * routines relating to the general flow.
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate #include "global.h"
310Sstevel@tonic-gate #include <stdio.h>
320Sstevel@tonic-gate #include <unistd.h>
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #include <signal.h>
350Sstevel@tonic-gate #include <memory.h>
360Sstevel@tonic-gate #include <string.h>
370Sstevel@tonic-gate #include <errno.h>
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #ifdef sparc
400Sstevel@tonic-gate #include <sys/hdio.h>
410Sstevel@tonic-gate #include <sys/dkbad.h>
420Sstevel@tonic-gate #endif
430Sstevel@tonic-gate 
440Sstevel@tonic-gate #include <sys/time.h>
450Sstevel@tonic-gate #include "main.h"
460Sstevel@tonic-gate #include "analyze.h"
470Sstevel@tonic-gate #include "menu.h"
480Sstevel@tonic-gate #include "param.h"
490Sstevel@tonic-gate #include "misc.h"
500Sstevel@tonic-gate #include "startup.h"
510Sstevel@tonic-gate #include "menu_command.h"
520Sstevel@tonic-gate #include "menu_partition.h"
530Sstevel@tonic-gate #include "prompts.h"
54767Ssjelinek #include "checkdev.h"
550Sstevel@tonic-gate #include "label.h"
560Sstevel@tonic-gate 
570Sstevel@tonic-gate extern	struct menu_item menu_command[];
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #ifdef	__STDC__
600Sstevel@tonic-gate 
610Sstevel@tonic-gate /*
620Sstevel@tonic-gate  *	Local prototypes for ANSI C compilers
630Sstevel@tonic-gate  */
640Sstevel@tonic-gate static void	get_disk_characteristics(void);
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 
670Sstevel@tonic-gate #else	/* __STDC__ */
680Sstevel@tonic-gate 
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate  *	Local prototypes for non-ANSI C compilers
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate static void	get_disk_characteristics();
730Sstevel@tonic-gate 
740Sstevel@tonic-gate #endif	/* __STDC__ */
750Sstevel@tonic-gate 
760Sstevel@tonic-gate /*
770Sstevel@tonic-gate  * This is the main entry point.
780Sstevel@tonic-gate  */
79362Sbg159949 int
main(int argc,char * argv[])80362Sbg159949 main(int argc, char *argv[])
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	int	i;
830Sstevel@tonic-gate 	int	ret_code = 1;
840Sstevel@tonic-gate 	char	**arglist;
850Sstevel@tonic-gate 	struct	disk_info *disk = NULL;
860Sstevel@tonic-gate 	struct	disk_type *type, *oldtype;
870Sstevel@tonic-gate 	struct	partition_info *parts;
880Sstevel@tonic-gate 	struct	sigaction act;
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 	solaris_offset = 0;
910Sstevel@tonic-gate 	/*
921564Slh195018 	 * Initialize cur_ctype to avoid null pointer dereference
931564Slh195018 	 * in auto_efi_sense().
941564Slh195018 	 */
951564Slh195018 	cur_ctype = (struct ctlr_type *)NULL;
961564Slh195018 	/*
970Sstevel@tonic-gate 	 * Decode the command line options.
980Sstevel@tonic-gate 	 */
990Sstevel@tonic-gate 	i = do_options(argc, argv);
1000Sstevel@tonic-gate 	/*
1010Sstevel@tonic-gate 	 * If we are to run from a command file, open it up.
1020Sstevel@tonic-gate 	 */
1030Sstevel@tonic-gate 	if (option_f) {
1040Sstevel@tonic-gate 		if (freopen(option_f, "r", stdin) == NULL) {
1050Sstevel@tonic-gate 			err_print("Unable to open command file '%s'.\n",
1066590Syl194034 			    option_f);
1070Sstevel@tonic-gate 			fullabort();
1080Sstevel@tonic-gate 		}
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 	/*
1110Sstevel@tonic-gate 	 * If we are logging, open the log file.
1120Sstevel@tonic-gate 	 */
1130Sstevel@tonic-gate 	if (option_l) {
1140Sstevel@tonic-gate 		if ((log_file = fopen(option_l, "w")) == NULL) {
1150Sstevel@tonic-gate 			err_print("Unable to open log file '%s'.\n",
1166590Syl194034 			    option_l);
1170Sstevel@tonic-gate 			fullabort();
1180Sstevel@tonic-gate 		}
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 	/*
1210Sstevel@tonic-gate 	 * Read in the data file and initialize the hardware structs.
1220Sstevel@tonic-gate 	 */
1230Sstevel@tonic-gate 	sup_init();
1240Sstevel@tonic-gate 	/*
1250Sstevel@tonic-gate 	 * If there are no disks on the command line, search the
1260Sstevel@tonic-gate 	 * appropriate device directory for character devices that
1270Sstevel@tonic-gate 	 * look like disks.
1280Sstevel@tonic-gate 	 */
1290Sstevel@tonic-gate 	if (i < 0) {
1300Sstevel@tonic-gate 		arglist = (char **)NULL;
1310Sstevel@tonic-gate 	/*
1320Sstevel@tonic-gate 	 * There were disks on the command line.  They comprise the
1330Sstevel@tonic-gate 	 * search list.
1340Sstevel@tonic-gate 	 */
1350Sstevel@tonic-gate 	} else {
1360Sstevel@tonic-gate 		arglist = &argv[i];
1370Sstevel@tonic-gate 	}
1380Sstevel@tonic-gate 	/*
1390Sstevel@tonic-gate 	 * Perform the search for disks.
1400Sstevel@tonic-gate 	 */
1410Sstevel@tonic-gate 	do_search(arglist);
1420Sstevel@tonic-gate 	/*
1430Sstevel@tonic-gate 	 * Catch ctrl-C and ctrl-Z so critical sections can be
1440Sstevel@tonic-gate 	 * implemented.  We use sigaction, as this sets up the
1450Sstevel@tonic-gate 	 * signal handler permanently, and also automatically
1460Sstevel@tonic-gate 	 * restarts any interrupted system call.
1470Sstevel@tonic-gate 	 */
1480Sstevel@tonic-gate 	act.sa_handler = cmdabort;
1490Sstevel@tonic-gate 	(void) memset(&act.sa_mask, 0, sizeof (sigset_t));
1500Sstevel@tonic-gate 	act.sa_flags = SA_RESTART | SA_NODEFER;
1510Sstevel@tonic-gate 	if (sigaction(SIGINT, &act, (struct sigaction *)NULL) == -1) {
1520Sstevel@tonic-gate 		err_print("sigaction(SIGINT) failed - %s\n",
1536590Syl194034 		    strerror(errno));
1540Sstevel@tonic-gate 		fullabort();
1550Sstevel@tonic-gate 	}
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	act.sa_handler = onsusp;
1580Sstevel@tonic-gate 	(void) memset(&act.sa_mask, 0, sizeof (sigset_t));
1590Sstevel@tonic-gate 	act.sa_flags = SA_RESTART | SA_NODEFER;
1600Sstevel@tonic-gate 	if (sigaction(SIGTSTP, &act, (struct sigaction *)NULL) == -1) {
1610Sstevel@tonic-gate 		err_print("sigaction(SIGTSTP) failed - %s\n",
1626590Syl194034 		    strerror(errno));
1630Sstevel@tonic-gate 		fullabort();
1640Sstevel@tonic-gate 	}
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	act.sa_handler = onalarm;
1670Sstevel@tonic-gate 	(void) memset(&act.sa_mask, 0, sizeof (sigset_t));
1680Sstevel@tonic-gate 	act.sa_flags = SA_RESTART;
1690Sstevel@tonic-gate 	if (sigaction(SIGALRM, &act, (struct sigaction *)NULL) == -1) {
1700Sstevel@tonic-gate 		err_print("sigaction(SIGALRM) failed - %s\n",
1716590Syl194034 		    strerror(errno));
1720Sstevel@tonic-gate 		fullabort();
1730Sstevel@tonic-gate 	}
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	/*
1760Sstevel@tonic-gate 	 * If there was only 1 disk on the command line, mark it
1770Sstevel@tonic-gate 	 * to be the current disk.  If it wasn't found, it's an error.
1780Sstevel@tonic-gate 	 */
1790Sstevel@tonic-gate 	if (i == argc - 1) {
1800Sstevel@tonic-gate 		disk = disk_list;
1810Sstevel@tonic-gate 		if (disk == NULL) {
1820Sstevel@tonic-gate 			err_print("Unable to find specified disk '%s'.\n",
1830Sstevel@tonic-gate 			    argv[i]);
1840Sstevel@tonic-gate 			fullabort();
1850Sstevel@tonic-gate 		}
1860Sstevel@tonic-gate 	}
1870Sstevel@tonic-gate 	/*
1880Sstevel@tonic-gate 	 * A disk was forced on the command line.
1890Sstevel@tonic-gate 	 */
1900Sstevel@tonic-gate 	if (option_d) {
1910Sstevel@tonic-gate 		/*
1920Sstevel@tonic-gate 		 * Find it in the list of found disks and mark it to
1930Sstevel@tonic-gate 		 * be the current disk.
1940Sstevel@tonic-gate 		 */
1950Sstevel@tonic-gate 		for (disk = disk_list; disk != NULL; disk = disk->disk_next)
1960Sstevel@tonic-gate 			if (diskname_match(option_d, disk))
1970Sstevel@tonic-gate 				break;
1980Sstevel@tonic-gate 		/*
1990Sstevel@tonic-gate 		 * If it wasn't found, it's an error.
2000Sstevel@tonic-gate 		 */
2010Sstevel@tonic-gate 		if (disk == NULL) {
2020Sstevel@tonic-gate 			err_print("Unable to find specified disk '%s'.\n",
2030Sstevel@tonic-gate 			    option_d);
2040Sstevel@tonic-gate 			fullabort();
2050Sstevel@tonic-gate 		}
2060Sstevel@tonic-gate 	}
2070Sstevel@tonic-gate 	/*
2080Sstevel@tonic-gate 	 * A disk type was forced on the command line.
2090Sstevel@tonic-gate 	 */
2100Sstevel@tonic-gate 	if (option_t != NULL) {
2110Sstevel@tonic-gate 		/*
2120Sstevel@tonic-gate 		 * Only legal if a disk was also forced.
2130Sstevel@tonic-gate 		 */
2140Sstevel@tonic-gate 		if (disk == NULL) {
2150Sstevel@tonic-gate 			err_print("Must specify disk as well as type.\n");
2160Sstevel@tonic-gate 			fullabort();
2170Sstevel@tonic-gate 		}
2180Sstevel@tonic-gate 		oldtype = disk->disk_type;
2190Sstevel@tonic-gate 		/*
2200Sstevel@tonic-gate 		 * Find the specified type in the list of legal types
2210Sstevel@tonic-gate 		 * for the disk.
2220Sstevel@tonic-gate 		 */
2230Sstevel@tonic-gate 		for (type = disk->disk_ctlr->ctlr_ctype->ctype_dlist;
2240Sstevel@tonic-gate 		    type != NULL; type = type->dtype_next)
2250Sstevel@tonic-gate 			if (strcmp(option_t, type->dtype_asciilabel) == 0)
2260Sstevel@tonic-gate 				break;
2270Sstevel@tonic-gate 		/*
2280Sstevel@tonic-gate 		 * If it wasn't found, it's an error.
2290Sstevel@tonic-gate 		 */
2300Sstevel@tonic-gate 		if (type == NULL) {
2310Sstevel@tonic-gate 			err_print(
2320Sstevel@tonic-gate "Specified type '%s' is not a known type.\n", option_t);
2330Sstevel@tonic-gate 			fullabort();
2340Sstevel@tonic-gate 		}
2350Sstevel@tonic-gate 		/*
2360Sstevel@tonic-gate 		 * If the specified type is not the same as the type
2370Sstevel@tonic-gate 		 * in the disk label, update the type and nullify the
2380Sstevel@tonic-gate 		 * partition map.
2390Sstevel@tonic-gate 		 */
2400Sstevel@tonic-gate 		if (type != oldtype) {
2410Sstevel@tonic-gate 			disk->disk_type = type;
2420Sstevel@tonic-gate 			disk->disk_parts = NULL;
2430Sstevel@tonic-gate 		}
2440Sstevel@tonic-gate 	}
2450Sstevel@tonic-gate 	/*
2460Sstevel@tonic-gate 	 * A partition map was forced on the command line.
2470Sstevel@tonic-gate 	 */
2480Sstevel@tonic-gate 	if (option_p) {
2490Sstevel@tonic-gate 		/*
2500Sstevel@tonic-gate 		 * Only legal if both disk and type were also forced.
2510Sstevel@tonic-gate 		 */
2520Sstevel@tonic-gate 		if (disk == NULL || disk->disk_type == NULL) {
2530Sstevel@tonic-gate 			err_print("Must specify disk and type as well ");
2540Sstevel@tonic-gate 			err_print("as partitiion.\n");
2550Sstevel@tonic-gate 			fullabort();
2560Sstevel@tonic-gate 		}
2570Sstevel@tonic-gate 		/*
2580Sstevel@tonic-gate 		 * Find the specified map in the list of legal maps
2590Sstevel@tonic-gate 		 * for the type.
2600Sstevel@tonic-gate 		 */
2610Sstevel@tonic-gate 		for (parts = disk->disk_type->dtype_plist; parts != NULL;
2620Sstevel@tonic-gate 		    parts = parts->pinfo_next)
2630Sstevel@tonic-gate 			if (strcmp(option_p, parts->pinfo_name) == 0)
2640Sstevel@tonic-gate 				break;
2650Sstevel@tonic-gate 		/*
2660Sstevel@tonic-gate 		 * If it wasn't found, it's an error.
2670Sstevel@tonic-gate 		 */
2680Sstevel@tonic-gate 		if (parts == NULL) {
2690Sstevel@tonic-gate 			err_print(
2700Sstevel@tonic-gate "Specified table '%s' is not a known table.\n", option_p);
2710Sstevel@tonic-gate 			fullabort();
2720Sstevel@tonic-gate 		}
2730Sstevel@tonic-gate 		/*
2740Sstevel@tonic-gate 		 * Update the map.
2750Sstevel@tonic-gate 		 */
2760Sstevel@tonic-gate 		disk->disk_parts = parts;
2770Sstevel@tonic-gate 	}
2780Sstevel@tonic-gate 	/*
2790Sstevel@tonic-gate 	 * If a disk was marked to become current, initialize the state
2800Sstevel@tonic-gate 	 * to make it current.  If not, ask user to pick one.
2810Sstevel@tonic-gate 	 */
2820Sstevel@tonic-gate 	if (disk != NULL) {
2830Sstevel@tonic-gate 		init_globals(disk);
2840Sstevel@tonic-gate 	} else if (option_f == 0 && option_d == 0) {
2850Sstevel@tonic-gate 		while (ret_code) {
2860Sstevel@tonic-gate 			ret_code = c_disk();
2870Sstevel@tonic-gate 		}
2880Sstevel@tonic-gate 	}
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate #ifdef	BUG1134748
2910Sstevel@tonic-gate 	/*
2920Sstevel@tonic-gate 	 * if -f command-file is specified, check for disk and disktype
2930Sstevel@tonic-gate 	 * input also. For SCSI disks, the type input may not be needed
2940Sstevel@tonic-gate 	 * since format would have figured that using inquiry information.
2950Sstevel@tonic-gate 	 */
2960Sstevel@tonic-gate 	if (option_f) {
2970Sstevel@tonic-gate 		if (cur_disk == NULL) {
2980Sstevel@tonic-gate 			err_print("Must specify a disk using -d option.\n");
2990Sstevel@tonic-gate 			fullabort();
3000Sstevel@tonic-gate 		}
3010Sstevel@tonic-gate 		if (cur_dtype == NULL) {
3020Sstevel@tonic-gate 			err_print("Must specify disk as well as type.\n");
3030Sstevel@tonic-gate 			fullabort();
3040Sstevel@tonic-gate 		}
3050Sstevel@tonic-gate 	}
3060Sstevel@tonic-gate #endif	/* BUG1134748 */
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	/*
3090Sstevel@tonic-gate 	 * Run the command menu.
3100Sstevel@tonic-gate 	 */
3110Sstevel@tonic-gate 	cur_menu = last_menu = 0;
3120Sstevel@tonic-gate 	run_menu(menu_command, "FORMAT", "format", 1);
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	/*
315362Sbg159949 	 * normal ending. Explicitly return(0);
3160Sstevel@tonic-gate 	 */
317362Sbg159949 	return (0);
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate /*
3210Sstevel@tonic-gate  * This routine initializes the internal state to ready it for a new
3220Sstevel@tonic-gate  * current disk.  There are a zillion state variables that store
3230Sstevel@tonic-gate  * information on the current disk, and they must all be updated.
3240Sstevel@tonic-gate  * We also tell SunOS about the disk, since it may not know if the
3250Sstevel@tonic-gate  * disk wasn't labeled at boot time.
3260Sstevel@tonic-gate  */
3270Sstevel@tonic-gate void
init_globals(disk)3280Sstevel@tonic-gate init_globals(disk)
3290Sstevel@tonic-gate 	struct	disk_info *disk;
3300Sstevel@tonic-gate {
3310Sstevel@tonic-gate 	int		status;
3326590Syl194034 	int		found_mount;
3336590Syl194034 	int		found_inuse;
3340Sstevel@tonic-gate #ifdef sparc
3350Sstevel@tonic-gate 	int		i;
3360Sstevel@tonic-gate 	caddr_t		bad_ptr = (caddr_t)&badmap;
3370Sstevel@tonic-gate #endif
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate 	/*
3400Sstevel@tonic-gate 	 * If there was an old current disk, close the file for it.
3410Sstevel@tonic-gate 	 */
3420Sstevel@tonic-gate 	if (cur_disk != NULL)
3430Sstevel@tonic-gate 		(void) close(cur_file);
3440Sstevel@tonic-gate 	/*
3450Sstevel@tonic-gate 	 * Kill off any defect lists still lying around.
3460Sstevel@tonic-gate 	 */
3470Sstevel@tonic-gate 	kill_deflist(&cur_list);
3480Sstevel@tonic-gate 	kill_deflist(&work_list);
3490Sstevel@tonic-gate 	/*
3500Sstevel@tonic-gate 	 * If there were any buffers, free them up.
3510Sstevel@tonic-gate 	 */
3520Sstevel@tonic-gate 	if ((char *)cur_buf != NULL) {
3530Sstevel@tonic-gate 		destroy_data((char *)cur_buf);
3540Sstevel@tonic-gate 		cur_buf = NULL;
3550Sstevel@tonic-gate 	}
3560Sstevel@tonic-gate 	if ((char *)pattern_buf != NULL) {
3570Sstevel@tonic-gate 		destroy_data((char *)pattern_buf);
3580Sstevel@tonic-gate 		pattern_buf = NULL;
3590Sstevel@tonic-gate 	}
3600Sstevel@tonic-gate 	/*
3610Sstevel@tonic-gate 	 * Fill in the hardware struct pointers for the new disk.
3620Sstevel@tonic-gate 	 */
3630Sstevel@tonic-gate 	cur_disk = disk;
3640Sstevel@tonic-gate 	cur_dtype = cur_disk->disk_type;
3650Sstevel@tonic-gate 	cur_label = cur_disk->label_type;
3660Sstevel@tonic-gate 	cur_ctlr = cur_disk->disk_ctlr;
3670Sstevel@tonic-gate 	cur_parts = cur_disk->disk_parts;
368*9889SLarry.Liu@Sun.COM 	cur_blksz = cur_disk->disk_lbasize;
3690Sstevel@tonic-gate 	cur_ctype = cur_ctlr->ctlr_ctype;
3700Sstevel@tonic-gate 	cur_ops = cur_ctype->ctype_ops;
3710Sstevel@tonic-gate 	cur_flags = 0;
3720Sstevel@tonic-gate 	/*
3730Sstevel@tonic-gate 	 * Open a file for the new disk.
3740Sstevel@tonic-gate 	 */
3750Sstevel@tonic-gate 	if ((cur_file = open_disk(cur_disk->disk_path,
3760Sstevel@tonic-gate 					O_RDWR | O_NDELAY)) < 0) {
3770Sstevel@tonic-gate 		err_print(
3780Sstevel@tonic-gate "Error: can't open selected disk '%s'.\n", cur_disk->disk_name);
3790Sstevel@tonic-gate 		fullabort();
3800Sstevel@tonic-gate 	}
3810Sstevel@tonic-gate #ifdef sparc
3820Sstevel@tonic-gate 	/*
3830Sstevel@tonic-gate 	 * If the new disk uses bad-144, initialize the bad block table.
3840Sstevel@tonic-gate 	 */
3850Sstevel@tonic-gate 	if (cur_ctlr->ctlr_flags & DKI_BAD144) {
3860Sstevel@tonic-gate 		badmap.bt_mbz = badmap.bt_csn = badmap.bt_flag = 0;
3870Sstevel@tonic-gate 		for (i = 0; i < NDKBAD; i++) {
3880Sstevel@tonic-gate 			badmap.bt_bad[i].bt_cyl = -1;
3890Sstevel@tonic-gate 			badmap.bt_bad[i].bt_trksec = -1;
3900Sstevel@tonic-gate 		}
3910Sstevel@tonic-gate 	}
3920Sstevel@tonic-gate #endif
3930Sstevel@tonic-gate 	/*
3940Sstevel@tonic-gate 	 * If the type of the new disk is known...
3950Sstevel@tonic-gate 	 */
3960Sstevel@tonic-gate 	if (cur_dtype != NULL) {
3970Sstevel@tonic-gate 		/*
3980Sstevel@tonic-gate 		 * Initialize the physical characteristics.
3990Sstevel@tonic-gate 		 * If need disk specs, prompt for undefined disk
4000Sstevel@tonic-gate 		 * characteristics.  If running from a file,
4010Sstevel@tonic-gate 		 * use defaults.
4020Sstevel@tonic-gate 		 */
4030Sstevel@tonic-gate 		if (cur_dtype->dtype_flags & DT_NEED_SPEFS) {
4040Sstevel@tonic-gate 			get_disk_characteristics();
4050Sstevel@tonic-gate 			cur_dtype->dtype_flags &= ~DT_NEED_SPEFS;
4060Sstevel@tonic-gate 		}
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 		ncyl = cur_dtype->dtype_ncyl;
4090Sstevel@tonic-gate 		acyl = cur_dtype->dtype_acyl;
4100Sstevel@tonic-gate 		pcyl = cur_dtype->dtype_pcyl;
4110Sstevel@tonic-gate 		nhead = cur_dtype->dtype_nhead;
4120Sstevel@tonic-gate 		nsect = cur_dtype->dtype_nsect;
4130Sstevel@tonic-gate 		phead = cur_dtype->dtype_phead;
4140Sstevel@tonic-gate 		psect = cur_dtype->dtype_psect;
4150Sstevel@tonic-gate 		/*
4160Sstevel@tonic-gate 		 * Alternates per cylinder are forced to 0 or 1,
4170Sstevel@tonic-gate 		 * independent of what the label says.  This works
4180Sstevel@tonic-gate 		 * because we know which ctlr we are dealing with.
4190Sstevel@tonic-gate 		 */
4200Sstevel@tonic-gate 		if (cur_ctype->ctype_flags & CF_APC)
4210Sstevel@tonic-gate 			apc = 1;
4220Sstevel@tonic-gate 		else
4230Sstevel@tonic-gate 			apc = 0;
4240Sstevel@tonic-gate 		/*
4250Sstevel@tonic-gate 		 * Initialize the surface analysis info.  We always start
4260Sstevel@tonic-gate 		 * out with scan set for the whole disk.  Note,
4270Sstevel@tonic-gate 		 * for SCSI disks, we can only scan the data area.
4280Sstevel@tonic-gate 		 */
4290Sstevel@tonic-gate 		scan_lower = 0;
4300Sstevel@tonic-gate 		scan_size = BUF_SECTS;
4310Sstevel@tonic-gate 		if ((cur_ctype->ctype_flags & CF_SCSI) &&
4320Sstevel@tonic-gate 		    (cur_disk->label_type == L_TYPE_SOLARIS)) {
4330Sstevel@tonic-gate 			scan_upper = datasects() - 1;
4340Sstevel@tonic-gate 		} else if (cur_disk->label_type == L_TYPE_SOLARIS) {
4350Sstevel@tonic-gate 			scan_upper = physsects() - 1;
4360Sstevel@tonic-gate 		} else if (cur_disk->label_type == L_TYPE_EFI) {
4370Sstevel@tonic-gate 			scan_upper = cur_parts->etoc->efi_last_lba;
4380Sstevel@tonic-gate 		}
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 		/*
4410Sstevel@tonic-gate 		 * Allocate the buffers.
4420Sstevel@tonic-gate 		 */
443*9889SLarry.Liu@Sun.COM 		cur_buf = (void *) zalloc(BUF_SECTS * cur_blksz);
444*9889SLarry.Liu@Sun.COM 		pattern_buf = (void *) zalloc(BUF_SECTS * cur_blksz);
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate 		/*
4470Sstevel@tonic-gate 		 * Tell the user which disk (s)he selected.
4480Sstevel@tonic-gate 		 */
4490Sstevel@tonic-gate 		if (chk_volname(cur_disk)) {
4500Sstevel@tonic-gate 			fmt_print("selecting %s: ", cur_disk->disk_name);
4510Sstevel@tonic-gate 			print_volname(cur_disk);
4520Sstevel@tonic-gate 			fmt_print("\n");
4530Sstevel@tonic-gate 		} else {
4540Sstevel@tonic-gate 			fmt_print("selecting %s\n", cur_disk->disk_name);
4550Sstevel@tonic-gate 		}
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 		/*
4580Sstevel@tonic-gate 		 * If the drive is formatted...
4590Sstevel@tonic-gate 		 */
4600Sstevel@tonic-gate 		if ((*cur_ops->op_ck_format)()) {
4610Sstevel@tonic-gate 			/*
4620Sstevel@tonic-gate 			 * Mark it formatted.
4630Sstevel@tonic-gate 			 */
4640Sstevel@tonic-gate 			cur_flags |= DISK_FORMATTED;
4650Sstevel@tonic-gate 			/*
4660Sstevel@tonic-gate 			 * Read the defect list, if we have one.
4670Sstevel@tonic-gate 			 */
4680Sstevel@tonic-gate 			if (!EMBEDDED_SCSI) {
4690Sstevel@tonic-gate 				read_list(&cur_list);
4700Sstevel@tonic-gate 			}
4710Sstevel@tonic-gate #ifdef sparc
4720Sstevel@tonic-gate 			/*
4730Sstevel@tonic-gate 			 * If the disk does BAD-144, we do an ioctl to
4740Sstevel@tonic-gate 			 * tell SunOS about the bad block table.
4750Sstevel@tonic-gate 			 */
4760Sstevel@tonic-gate 			if (cur_ctlr->ctlr_flags & DKI_BAD144) {
4770Sstevel@tonic-gate 				if (ioctl(cur_file, HDKIOCSBAD, &bad_ptr)) {
4780Sstevel@tonic-gate 					err_print(
4790Sstevel@tonic-gate "Warning: error telling SunOS bad block map table.\n");
4800Sstevel@tonic-gate 				}
4810Sstevel@tonic-gate 			}
4820Sstevel@tonic-gate #endif
4830Sstevel@tonic-gate 			fmt_print("[disk formatted");
4840Sstevel@tonic-gate 			if (!EMBEDDED_SCSI) {
4850Sstevel@tonic-gate 				if (cur_list.list != NULL) {
4860Sstevel@tonic-gate 					fmt_print(", defect list found");
4870Sstevel@tonic-gate 				} else {
4880Sstevel@tonic-gate 					fmt_print(", no defect list found");
4890Sstevel@tonic-gate 				}
4900Sstevel@tonic-gate 			}
4910Sstevel@tonic-gate 			fmt_print("]");
4920Sstevel@tonic-gate 		/*
4930Sstevel@tonic-gate 		 * Drive wasn't formatted.  Tell the user in case he
4940Sstevel@tonic-gate 		 * disagrees.
4950Sstevel@tonic-gate 		 */
4960Sstevel@tonic-gate 		} else if (EMBEDDED_SCSI) {
4970Sstevel@tonic-gate 			fmt_print("[disk unformatted]");
4980Sstevel@tonic-gate 		} else {
4990Sstevel@tonic-gate 			/*
5000Sstevel@tonic-gate 			 * Make sure the user is serious.  Note, for
5010Sstevel@tonic-gate 			 * SCSI disks since this is instantaneous, we
5020Sstevel@tonic-gate 			 * will just do it and not ask for confirmation.
5030Sstevel@tonic-gate 			 */
5040Sstevel@tonic-gate 			status = 0;
5050Sstevel@tonic-gate 			if (!(cur_ctype->ctype_flags & CF_CONFIRM)) {
5060Sstevel@tonic-gate 				if (check("\n\
5070Sstevel@tonic-gate Ready to get manufacturer's defect list from unformatted drive.\n\
5080Sstevel@tonic-gate This cannot be interrupted and takes a long while.\n\
5090Sstevel@tonic-gate Continue"))
5100Sstevel@tonic-gate 					status = 1;
5110Sstevel@tonic-gate 				else
5120Sstevel@tonic-gate 					fmt_print(
5130Sstevel@tonic-gate 				"Extracting manufacturer's defect list...");
5140Sstevel@tonic-gate 			}
5150Sstevel@tonic-gate 			/*
5160Sstevel@tonic-gate 			 * Extract manufacturer's defect list.
5170Sstevel@tonic-gate 			 */
5180Sstevel@tonic-gate 			if ((status == 0) && (cur_ops->op_ex_man != NULL)) {
5190Sstevel@tonic-gate 				status = (*cur_ops->op_ex_man)(&cur_list);
5200Sstevel@tonic-gate 			} else {
5210Sstevel@tonic-gate 				status = 1;
5220Sstevel@tonic-gate 			}
5230Sstevel@tonic-gate 			fmt_print("[disk unformatted");
5240Sstevel@tonic-gate 			if (status != 0) {
5250Sstevel@tonic-gate 				fmt_print(", no defect list found]");
5260Sstevel@tonic-gate 			} else {
5270Sstevel@tonic-gate 				fmt_print(", defect list found]");
5280Sstevel@tonic-gate 			}
5290Sstevel@tonic-gate 		}
5300Sstevel@tonic-gate 	} else {
5310Sstevel@tonic-gate 		/*
5320Sstevel@tonic-gate 		 * Disk type is not known.
5330Sstevel@tonic-gate 		 * Initialize physical characteristics to 0 and tell the
5340Sstevel@tonic-gate 		 * user we don't know what type the disk is.
5350Sstevel@tonic-gate 		 */
5360Sstevel@tonic-gate 		ncyl = acyl = nhead = nsect = psect = 0;
5370Sstevel@tonic-gate 	}
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 	fmt_print("\n");
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 	/*
5420Sstevel@tonic-gate 	 * Check to see if there are any mounted file systems on the
5430Sstevel@tonic-gate 	 * disk.  If there are, print a warning.
5440Sstevel@tonic-gate 	 */
5457563SPrasad.Singamsetty@Sun.COM 	if ((found_mount = checkmount((diskaddr_t)-1, (diskaddr_t)-1)) != 0)
5460Sstevel@tonic-gate 		err_print("Warning: Current Disk has mounted partitions.\n");
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate 	/*
549767Ssjelinek 	 * If any part of this device is also part of an SVM, VxVM or
550767Ssjelinek 	 * Live Upgrade device, print a warning.
551767Ssjelinek 	 */
5526590Syl194034 	found_inuse =  checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
553767Ssjelinek 	    (diskaddr_t)-1, 1, 0);
554767Ssjelinek 
555767Ssjelinek 	/*
5560Sstevel@tonic-gate 	 * Get the Solaris Fdisk Partition information
5570Sstevel@tonic-gate 	 */
5580Sstevel@tonic-gate 	(void) copy_solaris_part(&cur_disk->fdisk_part);
5596590Syl194034 
5606590Syl194034 	if (!found_mount && !found_inuse &&
5616590Syl194034 	    cur_disk->label_type == L_TYPE_EFI) {
5626590Syl194034 
5636590Syl194034 		/*
5646590Syl194034 		 * If alter_lba is 1, we are using the backup label.
5656590Syl194034 		 * Since we can locate the backup label by disk capacity,
5666590Syl194034 		 * there must be no space expanded after backup label.
5676590Syl194034 		 */
5686590Syl194034 		if ((cur_parts->etoc->efi_altern_lba != 1) &&
5696590Syl194034 		    (cur_parts->etoc->efi_altern_lba <
5706590Syl194034 		    cur_parts->etoc->efi_last_lba)) {
5716590Syl194034 
5726590Syl194034 			/*
5736590Syl194034 			 * Lun expansion detected. Prompt user now and actually
5746590Syl194034 			 * adjust the label in <partition> command.
5756590Syl194034 			 */
5766590Syl194034 			fmt_print(
5776590Syl194034 "Note: capacity in disk label is smaller than the real disk capacity.\n\
5786590Syl194034 Select <partition> <expand> to adjust the label capacity. \n");
5796590Syl194034 		}
5806590Syl194034 	}
5810Sstevel@tonic-gate }
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 
5840Sstevel@tonic-gate /*
5850Sstevel@tonic-gate  * Prompt for some undefined disk characteristics.
5860Sstevel@tonic-gate  * Used when there is no disk definition, but the
5870Sstevel@tonic-gate  * disk has a valid label, so basically we're
5880Sstevel@tonic-gate  * prompting for everything that isn't in the label.
5890Sstevel@tonic-gate  */
5900Sstevel@tonic-gate static void
get_disk_characteristics()5910Sstevel@tonic-gate get_disk_characteristics()
5920Sstevel@tonic-gate {
5930Sstevel@tonic-gate 	/*
5940Sstevel@tonic-gate 	 * The need_spefs flag is used to tell us that this disk
5950Sstevel@tonic-gate 	 * is not a known type and the ctlr specific info must
5960Sstevel@tonic-gate 	 * be prompted for.  We only prompt for the info that applies
5970Sstevel@tonic-gate 	 * to this ctlr.
5980Sstevel@tonic-gate 	 */
5990Sstevel@tonic-gate 	assert(cur_dtype->dtype_flags & DT_NEED_SPEFS);
6000Sstevel@tonic-gate 
6010Sstevel@tonic-gate 	/*
6020Sstevel@tonic-gate 	 * If we're running with input from a file, use
6030Sstevel@tonic-gate 	 * reasonable defaults, since prompting for the
6040Sstevel@tonic-gate 	 * information will probably mess things up.
6050Sstevel@tonic-gate 	 */
6060Sstevel@tonic-gate 	if (option_f) {
6070Sstevel@tonic-gate 		cur_dtype->dtype_pcyl = ncyl + acyl;
6080Sstevel@tonic-gate 		cur_dtype->dtype_rpm = AVG_RPM;
6090Sstevel@tonic-gate 		cur_dtype->dtype_bpt = INFINITY;
6100Sstevel@tonic-gate 		cur_dtype->dtype_phead = 0;
6110Sstevel@tonic-gate 		cur_dtype->dtype_psect = 0;
6120Sstevel@tonic-gate 		cur_dtype->dtype_cyl_skew = 0;
6130Sstevel@tonic-gate 		cur_dtype->dtype_trk_skew = 0;
6140Sstevel@tonic-gate 		cur_dtype->dtype_trks_zone = 0;
6150Sstevel@tonic-gate 		cur_dtype->dtype_atrks = 0;
6160Sstevel@tonic-gate 		cur_dtype->dtype_asect = 0;
6170Sstevel@tonic-gate 		cur_dtype->dtype_cache = 0;
6180Sstevel@tonic-gate 		cur_dtype->dtype_threshold = 0;
6190Sstevel@tonic-gate 		cur_dtype->dtype_prefetch_min = 0;
6200Sstevel@tonic-gate 		cur_dtype->dtype_prefetch_max = 0;
6210Sstevel@tonic-gate 
6220Sstevel@tonic-gate 		if (cur_ctype->ctype_flags & CF_SMD_DEFS) {
6230Sstevel@tonic-gate 			cur_dtype->dtype_bps = AVG_BPS;
6240Sstevel@tonic-gate 		}
6250Sstevel@tonic-gate 	} else {
6260Sstevel@tonic-gate 
6270Sstevel@tonic-gate 		cur_dtype->dtype_pcyl = get_pcyl(ncyl, cur_dtype->dtype_acyl);
6280Sstevel@tonic-gate 		cur_dtype->dtype_bpt = get_bpt(cur_dtype->dtype_nsect,
6296590Syl194034 		    &cur_dtype->dtype_options);
6300Sstevel@tonic-gate 		cur_dtype->dtype_rpm = get_rpm();
6310Sstevel@tonic-gate 		cur_dtype->dtype_fmt_time =
6326590Syl194034 		    get_fmt_time(&cur_dtype->dtype_options);
6330Sstevel@tonic-gate 		cur_dtype->dtype_cyl_skew =
6346590Syl194034 		    get_cyl_skew(&cur_dtype->dtype_options);
6350Sstevel@tonic-gate 		cur_dtype->dtype_trk_skew =
6366590Syl194034 		    get_trk_skew(&cur_dtype->dtype_options);
6370Sstevel@tonic-gate 		cur_dtype->dtype_trks_zone =
6386590Syl194034 		    get_trks_zone(&cur_dtype->dtype_options);
6390Sstevel@tonic-gate 		cur_dtype->dtype_atrks = get_atrks(&cur_dtype->dtype_options);
6400Sstevel@tonic-gate 		cur_dtype->dtype_asect = get_asect(&cur_dtype->dtype_options);
6410Sstevel@tonic-gate 		cur_dtype->dtype_cache = get_cache(&cur_dtype->dtype_options);
6420Sstevel@tonic-gate 		cur_dtype->dtype_threshold =
6436590Syl194034 		    get_threshold(&cur_dtype->dtype_options);
6440Sstevel@tonic-gate 		cur_dtype->dtype_prefetch_min =
6456590Syl194034 		    get_min_prefetch(&cur_dtype->dtype_options);
6460Sstevel@tonic-gate 		cur_dtype->dtype_prefetch_max =
6476590Syl194034 		    get_max_prefetch(cur_dtype->dtype_prefetch_min,
6486590Syl194034 		    &cur_dtype->dtype_options);
6490Sstevel@tonic-gate 		cur_dtype->dtype_phead =
6506590Syl194034 		    get_phead(nhead, &cur_dtype->dtype_options);
6510Sstevel@tonic-gate 		cur_dtype->dtype_psect = get_psect(&cur_dtype->dtype_options);
6520Sstevel@tonic-gate 		cur_dtype->dtype_bps = get_bps();
6530Sstevel@tonic-gate #ifdef sparc
6540Sstevel@tonic-gate 		cur_dtype->dtype_dr_type = 0;
6550Sstevel@tonic-gate #endif
6560Sstevel@tonic-gate 	}
6570Sstevel@tonic-gate }
658