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