1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This file contains functions to implement automatic configuration 28 * of scsi disks. 29 */ 30 #include "global.h" 31 32 #include <fcntl.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <strings.h> 36 #include <stdlib.h> 37 #include <ctype.h> 38 39 #include "misc.h" 40 #include "param.h" 41 #include "ctlr_scsi.h" 42 #include "auto_sense.h" 43 #include "partition.h" 44 #include "label.h" 45 #include "startup.h" 46 #include "analyze.h" 47 #include "io.h" 48 #include "hardware_structs.h" 49 #include "menu_fdisk.h" 50 51 52 #define DISK_NAME_MAX 256 53 54 extern int nctypes; 55 extern struct ctlr_type ctlr_types[]; 56 57 58 /* 59 * Marker for free hog partition 60 */ 61 #define HOG (-1) 62 63 64 65 /* 66 * Default partition tables 67 * 68 * Disk capacity root swap usr 69 * ------------- ---- ---- --- 70 * 0mb to 64mb 0 0 remainder 71 * 64mb to 180mb 16mb 16mb remainder 72 * 180mb to 280mb 16mb 32mb remainder 73 * 280mb to 380mb 24mb 32mb remainder 74 * 380mb to 600mb 32mb 32mb remainder 75 * 600mb to 1gb 32mb 64mb remainder 76 * 1gb to 2gb 64mb 128mb remainder 77 * 2gb on up 128mb 128mb remainder 78 */ 79 struct part_table { 80 int partitions[NDKMAP]; 81 }; 82 83 static struct part_table part_table_64mb = { 84 { 0, 0, 0, 0, 0, 0, HOG, 0} 85 }; 86 87 static struct part_table part_table_180mb = { 88 { 16, 16, 0, 0, 0, 0, HOG, 0} 89 }; 90 91 static struct part_table part_table_280mb = { 92 { 16, 32, 0, 0, 0, 0, HOG, 0} 93 }; 94 95 static struct part_table part_table_380mb = { 96 { 24, 32, 0, 0, 0, 0, HOG, 0} 97 }; 98 99 static struct part_table part_table_600mb = { 100 { 32, 32, 0, 0, 0, 0, HOG, 0} 101 }; 102 103 static struct part_table part_table_1gb = { 104 { 32, 64, 0, 0, 0, 0, HOG, 0} 105 }; 106 107 static struct part_table part_table_2gb = { 108 { 64, 128, 0, 0, 0, 0, HOG, 0} 109 }; 110 111 static struct part_table part_table_infinity = { 112 { 128, 128, 0, 0, 0, 0, HOG, 0} 113 }; 114 115 116 static struct default_partitions { 117 diskaddr_t min_capacity; 118 diskaddr_t max_capacity; 119 struct part_table *part_table; 120 } default_partitions[] = { 121 { 0, 64, &part_table_64mb }, /* 0 to 64 mb */ 122 { 64, 180, &part_table_180mb }, /* 64 to 180 mb */ 123 { 180, 280, &part_table_280mb }, /* 180 to 280 mb */ 124 { 280, 380, &part_table_380mb }, /* 280 to 380 mb */ 125 { 380, 600, &part_table_600mb }, /* 380 to 600 mb */ 126 { 600, 1024, &part_table_1gb }, /* 600 to 1 gb */ 127 { 1024, 2048, &part_table_2gb }, /* 1 to 2 gb */ 128 { 2048, INFINITY, &part_table_infinity }, /* 2 gb on up */ 129 }; 130 131 #define DEFAULT_PARTITION_TABLE_SIZE \ 132 (sizeof (default_partitions) / sizeof (struct default_partitions)) 133 134 /* 135 * msgs for check() 136 */ 137 #define FORMAT_MSG "Auto configuration via format.dat" 138 #define GENERIC_MSG "Auto configuration via generic SCSI-2" 139 140 /* 141 * Disks on symbios(Hardwire raid controller) return a fixed number 142 * of heads(64)/cylinders(64) and adjust the cylinders depending 143 * capacity of the configured lun. 144 * In such a case we get number of physical cylinders < 3 which 145 * is the minimum required by solaris(2 reserved + 1 data cylinders). 146 * Hence try to adjust the cylinders by reducing the "nsect/nhead". 147 * 148 */ 149 /* 150 * assuming a minimum of 32 block cylinders. 151 */ 152 #define MINIMUM_NO_HEADS 2 153 #define MINIMUM_NO_SECTORS 16 154 155 #define MINIMUM_NO_CYLINDERS 128 156 157 #if defined(_SUNOS_VTOC_8) 158 159 /* These are 16-bit fields */ 160 #define MAXIMUM_NO_HEADS 65535 161 #define MAXIMUM_NO_SECTORS 65535 162 #define MAXIMUM_NO_CYLINDERS 65535 163 164 #endif /* defined(_SUNOS_VTOC_8) */ 165 166 /* 167 * minimum number of cylinders required by Solaris. 168 */ 169 #define SUN_MIN_CYL 3 170 171 172 173 /* 174 * ANSI prototypes for local static functions 175 */ 176 static struct disk_type *generic_disk_sense( 177 int fd, 178 int can_prompt, 179 struct dk_label *label, 180 struct scsi_inquiry *inquiry, 181 struct scsi_capacity_16 *capacity, 182 char *disk_name); 183 static int use_existing_disk_type( 184 int fd, 185 int can_prompt, 186 struct dk_label *label, 187 struct scsi_inquiry *inquiry, 188 struct disk_type *disk_type, 189 struct scsi_capacity_16 *capacity); 190 int build_default_partition(struct dk_label *label, 191 int ctrl_type); 192 static struct disk_type *find_scsi_disk_type( 193 char *disk_name, 194 struct dk_label *label); 195 static struct disk_type *find_scsi_disk_by_name( 196 char *disk_name); 197 static struct ctlr_type *find_scsi_ctlr_type(void); 198 static struct ctlr_info *find_scsi_ctlr_info( 199 struct dk_cinfo *dkinfo); 200 static struct disk_type *new_scsi_disk_type( 201 int fd, 202 char *disk_name, 203 struct dk_label *label); 204 static struct disk_info *find_scsi_disk_info( 205 struct dk_cinfo *dkinfo); 206 207 static struct disk_type *new_direct_disk_type(int fd, char *disk_name, 208 struct dk_label *label); 209 210 static struct disk_info *find_direct_disk_info(struct dk_cinfo *dkinfo); 211 static int efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc); 212 static int auto_label_init(struct dk_label *label); 213 static struct ctlr_type *find_direct_ctlr_type(void); 214 static struct ctlr_info *find_direct_ctlr_info(struct dk_cinfo *dkinfo); 215 static struct disk_info *find_direct_disk_info(struct dk_cinfo *dkinfo); 216 static struct ctlr_type *find_vbd_ctlr_type(void); 217 static struct ctlr_info *find_vbd_ctlr_info(struct dk_cinfo *dkinfo); 218 static struct disk_info *find_vbd_disk_info(struct dk_cinfo *dkinfo); 219 220 static char *get_sun_disk_name( 221 char *disk_name, 222 struct scsi_inquiry *inquiry); 223 static char *get_generic_disk_name( 224 char *disk_name, 225 struct scsi_inquiry *inquiry); 226 static int force_blocksize(int fd); 227 static int raw_format(int fd); 228 static char *strcopy( 229 char *dst, 230 char *src, 231 int n); 232 static int adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl, 233 uint_t *nsect, uint_t *nhead); 234 static void compute_chs_values(diskaddr_t total_capacity, 235 diskaddr_t usable_capacity, uint_t *pcylp, 236 uint_t *nheadp, uint_t *nsectp); 237 #if defined(_SUNOS_VTOC_8) 238 static diskaddr_t square_box( 239 diskaddr_t capacity, 240 uint_t *dim1, uint_t lim1, 241 uint_t *dim2, uint_t lim2, 242 uint_t *dim3, uint_t lim3); 243 #endif /* defined(_SUNOS_VTOC_8) */ 244 245 246 /* 247 * We need to get information necessary to construct a *new* efi 248 * label type 249 */ 250 struct disk_type * 251 auto_efi_sense(int fd, struct efi_info *label) 252 { 253 254 struct dk_gpt *vtoc; 255 int i; 256 257 struct disk_type *disk, *dp; 258 struct disk_info *disk_info; 259 struct ctlr_info *ctlr; 260 struct dk_cinfo dkinfo; 261 struct partition_info *part; 262 263 /* 264 * get vendor, product, revision and capacity info. 265 */ 266 if (get_disk_info(fd, label) == -1) { 267 return ((struct disk_type *)NULL); 268 } 269 /* 270 * Now build the default partition table 271 */ 272 if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) { 273 err_print("efi_alloc_and_init failed. \n"); 274 return ((struct disk_type *)NULL); 275 } 276 277 label->e_parts = vtoc; 278 279 /* 280 * Create a whole hog EFI partition table: 281 * S0 takes the whole disk except the primary EFI label, 282 * backup EFI label, and the reserved partition. 283 */ 284 vtoc->efi_parts[0].p_tag = V_USR; 285 vtoc->efi_parts[0].p_start = vtoc->efi_first_u_lba; 286 vtoc->efi_parts[0].p_size = vtoc->efi_last_u_lba - vtoc->efi_first_u_lba 287 - EFI_MIN_RESV_SIZE + 1; 288 289 /* 290 * S1-S6 are unassigned slices. 291 */ 292 for (i = 1; i < vtoc->efi_nparts - 2; i ++) { 293 vtoc->efi_parts[i].p_tag = V_UNASSIGNED; 294 vtoc->efi_parts[i].p_start = 0; 295 vtoc->efi_parts[i].p_size = 0; 296 } 297 298 /* 299 * The reserved slice 300 */ 301 vtoc->efi_parts[vtoc->efi_nparts - 1].p_tag = V_RESERVED; 302 vtoc->efi_parts[vtoc->efi_nparts - 1].p_start = 303 vtoc->efi_last_u_lba - EFI_MIN_RESV_SIZE + 1; 304 vtoc->efi_parts[vtoc->efi_nparts - 1].p_size = EFI_MIN_RESV_SIZE; 305 306 /* 307 * Now stick all of it into the disk_type struct 308 */ 309 310 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { 311 if (option_msg && diag_msg) { 312 err_print("DKIOCINFO failed\n"); 313 } 314 return (NULL); 315 } 316 if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT)) { 317 ctlr = find_direct_ctlr_info(&dkinfo); 318 disk_info = find_direct_disk_info(&dkinfo); 319 } else if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_VBD)) { 320 ctlr = find_vbd_ctlr_info(&dkinfo); 321 disk_info = find_vbd_disk_info(&dkinfo); 322 } else { 323 ctlr = find_scsi_ctlr_info(&dkinfo); 324 disk_info = find_scsi_disk_info(&dkinfo); 325 } 326 disk = (struct disk_type *)zalloc(sizeof (struct disk_type)); 327 assert(disk_info->disk_ctlr == ctlr); 328 dp = ctlr->ctlr_ctype->ctype_dlist; 329 if (dp == NULL) { 330 ctlr->ctlr_ctype->ctype_dlist = dp; 331 } else { 332 while (dp->dtype_next != NULL) { 333 dp = dp->dtype_next; 334 } 335 dp->dtype_next = disk; 336 } 337 disk->dtype_next = NULL; 338 339 (void) strlcpy(disk->vendor, label->vendor, 340 sizeof (disk->vendor)); 341 (void) strlcpy(disk->product, label->product, 342 sizeof (disk->product)); 343 (void) strlcpy(disk->revision, label->revision, 344 sizeof (disk->revision)); 345 disk->capacity = label->capacity; 346 347 part = (struct partition_info *) 348 zalloc(sizeof (struct partition_info)); 349 disk->dtype_plist = part; 350 351 part->pinfo_name = alloc_string("default"); 352 part->pinfo_next = NULL; 353 part->etoc = vtoc; 354 355 bzero(disk_info->v_volume, LEN_DKL_VVOL); 356 disk_info->disk_parts = part; 357 return (disk); 358 } 359 360 static int 361 efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc) 362 { 363 void *data = dk_ioc->dki_data; 364 int error; 365 366 dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data; 367 error = ioctl(fd, cmd, (void *)dk_ioc); 368 dk_ioc->dki_data = data; 369 370 return (error); 371 } 372 373 static struct ctlr_type * 374 find_direct_ctlr_type() 375 { 376 struct mctlr_list *mlp; 377 378 mlp = controlp; 379 380 while (mlp != NULL) { 381 if (mlp->ctlr_type->ctype_ctype == DKC_DIRECT) { 382 return (mlp->ctlr_type); 383 } 384 mlp = mlp->next; 385 } 386 387 impossible("no DIRECT controller type"); 388 389 return ((struct ctlr_type *)NULL); 390 } 391 392 static struct ctlr_type * 393 find_vbd_ctlr_type() 394 { 395 struct mctlr_list *mlp; 396 397 mlp = controlp; 398 399 while (mlp != NULL) { 400 if (mlp->ctlr_type->ctype_ctype == DKC_VBD) { 401 return (mlp->ctlr_type); 402 } 403 mlp = mlp->next; 404 } 405 406 impossible("no VBD controller type"); 407 408 return ((struct ctlr_type *)NULL); 409 } 410 411 static struct ctlr_info * 412 find_direct_ctlr_info( 413 struct dk_cinfo *dkinfo) 414 { 415 struct ctlr_info *ctlr; 416 417 if (dkinfo->dki_ctype != DKC_DIRECT) 418 return (NULL); 419 420 for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) { 421 if (ctlr->ctlr_addr == dkinfo->dki_addr && 422 ctlr->ctlr_space == dkinfo->dki_space && 423 ctlr->ctlr_ctype->ctype_ctype == DKC_DIRECT) { 424 return (ctlr); 425 } 426 } 427 428 impossible("no DIRECT controller info"); 429 /*NOTREACHED*/ 430 } 431 432 static struct ctlr_info * 433 find_vbd_ctlr_info( 434 struct dk_cinfo *dkinfo) 435 { 436 struct ctlr_info *ctlr; 437 438 if (dkinfo->dki_ctype != DKC_VBD) 439 return (NULL); 440 441 for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) { 442 if (ctlr->ctlr_addr == dkinfo->dki_addr && 443 ctlr->ctlr_space == dkinfo->dki_space && 444 ctlr->ctlr_ctype->ctype_ctype == DKC_VBD) { 445 return (ctlr); 446 } 447 } 448 449 impossible("no VBD controller info"); 450 /*NOTREACHED*/ 451 } 452 453 static struct disk_info * 454 find_direct_disk_info( 455 struct dk_cinfo *dkinfo) 456 { 457 struct disk_info *disk; 458 struct dk_cinfo *dp; 459 460 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 461 assert(dkinfo->dki_ctype == DKC_DIRECT); 462 dp = &disk->disk_dkinfo; 463 if (dp->dki_ctype == dkinfo->dki_ctype && 464 dp->dki_cnum == dkinfo->dki_cnum && 465 dp->dki_unit == dkinfo->dki_unit && 466 strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) { 467 return (disk); 468 } 469 } 470 471 impossible("No DIRECT disk info instance\n"); 472 /*NOTREACHED*/ 473 } 474 475 static struct disk_info * 476 find_vbd_disk_info( 477 struct dk_cinfo *dkinfo) 478 { 479 struct disk_info *disk; 480 struct dk_cinfo *dp; 481 482 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 483 assert(dkinfo->dki_ctype == DKC_VBD); 484 dp = &disk->disk_dkinfo; 485 if (dp->dki_ctype == dkinfo->dki_ctype && 486 dp->dki_cnum == dkinfo->dki_cnum && 487 dp->dki_unit == dkinfo->dki_unit && 488 strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) { 489 return (disk); 490 } 491 } 492 493 impossible("No VBD disk info instance\n"); 494 /*NOTREACHED*/ 495 } 496 497 /* 498 * To convert EFI to SMI labels, we need to get label geometry. 499 * Unfortunately at this time there is no good way to do so. 500 * DKIOCGGEOM will fail if disk is EFI labeled. So we hack around 501 * it and clear EFI label, do a DKIOCGGEOM and put the EFI label 502 * back on disk. 503 * This routine gets the label geometry and initializes the label 504 * It uses cur_file as opened device. 505 * returns 0 if succeeds or -1 if failed. 506 */ 507 static int 508 auto_label_init(struct dk_label *label) 509 { 510 dk_efi_t dk_ioc; 511 dk_efi_t dk_ioc_back; 512 efi_gpt_t *data = NULL; 513 efi_gpt_t *databack = NULL; 514 struct dk_geom disk_geom; 515 struct dk_minfo disk_info; 516 efi_gpt_t *backsigp; 517 int fd = cur_file; 518 int rval = -1; 519 int efisize = EFI_LABEL_SIZE * 2; 520 int success = 0; 521 uint64_t sig; 522 uint64_t backsig; 523 524 if ((data = calloc(efisize, 1)) == NULL) { 525 err_print("auto_label_init: calloc failed\n"); 526 goto auto_label_init_out; 527 } 528 529 dk_ioc.dki_data = data; 530 dk_ioc.dki_lba = 1; 531 dk_ioc.dki_length = efisize; 532 533 if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) != 0) { 534 err_print("auto_label_init: GETEFI failed\n"); 535 goto auto_label_init_out; 536 } 537 538 if ((databack = calloc(efisize, 1)) == NULL) { 539 err_print("auto_label_init calloc2 failed"); 540 goto auto_label_init_out; 541 } 542 543 /* get the LBA size and capacity */ 544 if (ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info) == -1) { 545 err_print("auto_label_init: dkiocgmediainfo failed\n"); 546 goto auto_label_init_out; 547 } 548 549 if (disk_info.dki_lbsize == 0) { 550 if (option_msg && diag_msg) { 551 err_print("auto_lbal_init: assuming 512 byte" 552 "block size"); 553 } 554 disk_info.dki_lbsize = DEV_BSIZE; 555 } 556 557 if (disk_info.dki_lbsize != DEV_BSIZE) { 558 err_print("auto_label_init: lbasize is not 512\n"); 559 goto auto_label_init_out; 560 } 561 562 dk_ioc_back.dki_data = databack; 563 564 /* 565 * back up efi label goes to capacity - 1, we are reading an extra block 566 * before the back up label. 567 */ 568 dk_ioc_back.dki_lba = disk_info.dki_capacity - 1 - 1; 569 dk_ioc_back.dki_length = efisize; 570 571 if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc_back) != 0) { 572 err_print("auto_label_init: GETEFI backup failed\n"); 573 goto auto_label_init_out; 574 } 575 576 sig = dk_ioc.dki_data->efi_gpt_Signature; 577 dk_ioc.dki_data->efi_gpt_Signature = 0x0; 578 579 enter_critical(); 580 581 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { 582 err_print("auto_label_init: SETEFI failed\n"); 583 exit_critical(); 584 goto auto_label_init_out; 585 } 586 587 backsigp = (efi_gpt_t *)((uintptr_t)dk_ioc_back.dki_data + DEV_BSIZE); 588 589 backsig = backsigp->efi_gpt_Signature; 590 591 backsigp->efi_gpt_Signature = 0; 592 593 if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc_back) == -1) { 594 err_print("auto_label_init: SETEFI backup failed\n"); 595 } 596 597 if (ioctl(cur_file, DKIOCGGEOM, &disk_geom) != 0) 598 err_print("auto_label_init: GGEOM failed\n"); 599 else 600 success = 1; 601 602 dk_ioc.dki_data->efi_gpt_Signature = sig; 603 backsigp->efi_gpt_Signature = backsig; 604 605 if (efi_ioctl(cur_file, DKIOCSETEFI, &dk_ioc_back) == -1) { 606 err_print("auto_label_init: SETEFI revert backup failed\n"); 607 success = 0; 608 } 609 610 if (efi_ioctl(cur_file, DKIOCSETEFI, &dk_ioc) == -1) { 611 err_print("auto_label_init: SETEFI revert failed\n"); 612 success = 0; 613 } 614 615 exit_critical(); 616 617 if (success == 0) 618 goto auto_label_init_out; 619 620 ncyl = disk_geom.dkg_ncyl; 621 acyl = disk_geom.dkg_acyl; 622 nhead = disk_geom.dkg_nhead; 623 nsect = disk_geom.dkg_nsect; 624 pcyl = ncyl + acyl; 625 626 label->dkl_pcyl = pcyl; 627 label->dkl_ncyl = ncyl; 628 label->dkl_acyl = acyl; 629 label->dkl_nhead = nhead; 630 label->dkl_nsect = nsect; 631 label->dkl_apc = 0; 632 label->dkl_intrlv = 1; 633 label->dkl_rpm = disk_geom.dkg_rpm; 634 635 label->dkl_magic = DKL_MAGIC; 636 637 (void) snprintf(label->dkl_asciilabel, sizeof (label->dkl_asciilabel), 638 "%s cyl %u alt %u hd %u sec %u", 639 "DEFAULT", ncyl, acyl, nhead, nsect); 640 641 rval = 0; 642 #if defined(_FIRMWARE_NEEDS_FDISK) 643 (void) auto_solaris_part(label); 644 ncyl = label->dkl_ncyl; 645 646 #endif /* defined(_FIRMWARE_NEEDS_FDISK) */ 647 648 if (!build_default_partition(label, DKC_DIRECT)) { 649 rval = -1; 650 } 651 652 (void) checksum(label, CK_MAKESUM); 653 654 655 auto_label_init_out: 656 if (data) 657 free(data); 658 if (databack) 659 free(databack); 660 661 return (rval); 662 } 663 664 static struct disk_type * 665 new_direct_disk_type( 666 int fd, 667 char *disk_name, 668 struct dk_label *label) 669 { 670 struct disk_type *dp; 671 struct disk_type *disk; 672 struct ctlr_info *ctlr; 673 struct dk_cinfo dkinfo; 674 struct partition_info *part = NULL; 675 struct partition_info *pt; 676 struct disk_info *disk_info; 677 int i; 678 679 /* 680 * Get the disk controller info for this disk 681 */ 682 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { 683 if (option_msg && diag_msg) { 684 err_print("DKIOCINFO failed\n"); 685 } 686 return (NULL); 687 } 688 689 /* 690 * Find the ctlr_info for this disk. 691 */ 692 ctlr = find_direct_ctlr_info(&dkinfo); 693 694 /* 695 * Allocate a new disk type for the direct controller. 696 */ 697 disk = (struct disk_type *)zalloc(sizeof (struct disk_type)); 698 699 /* 700 * Find the disk_info instance for this disk. 701 */ 702 disk_info = find_direct_disk_info(&dkinfo); 703 704 /* 705 * The controller and the disk should match. 706 */ 707 assert(disk_info->disk_ctlr == ctlr); 708 709 /* 710 * Link the disk into the list of disks 711 */ 712 dp = ctlr->ctlr_ctype->ctype_dlist; 713 if (dp == NULL) { 714 ctlr->ctlr_ctype->ctype_dlist = dp; 715 } else { 716 while (dp->dtype_next != NULL) { 717 dp = dp->dtype_next; 718 } 719 dp->dtype_next = disk; 720 } 721 disk->dtype_next = NULL; 722 723 /* 724 * Allocate and initialize the disk name. 725 */ 726 disk->dtype_asciilabel = alloc_string(disk_name); 727 728 /* 729 * Initialize disk geometry info 730 */ 731 disk->dtype_pcyl = label->dkl_pcyl; 732 disk->dtype_ncyl = label->dkl_ncyl; 733 disk->dtype_acyl = label->dkl_acyl; 734 disk->dtype_nhead = label->dkl_nhead; 735 disk->dtype_nsect = label->dkl_nsect; 736 disk->dtype_rpm = label->dkl_rpm; 737 738 part = (struct partition_info *) 739 zalloc(sizeof (struct partition_info)); 740 pt = disk->dtype_plist; 741 if (pt == NULL) { 742 disk->dtype_plist = part; 743 } else { 744 while (pt->pinfo_next != NULL) { 745 pt = pt->pinfo_next; 746 } 747 pt->pinfo_next = part; 748 } 749 750 part->pinfo_next = NULL; 751 752 /* 753 * Set up the partition name 754 */ 755 part->pinfo_name = alloc_string("default"); 756 757 /* 758 * Fill in the partition info from the label 759 */ 760 for (i = 0; i < NDKMAP; i++) { 761 762 #if defined(_SUNOS_VTOC_8) 763 part->pinfo_map[i] = label->dkl_map[i]; 764 765 #elif defined(_SUNOS_VTOC_16) 766 part->pinfo_map[i].dkl_cylno = 767 label->dkl_vtoc.v_part[i].p_start / 768 ((blkaddr_t)(disk->dtype_nhead * 769 disk->dtype_nsect - apc)); 770 part->pinfo_map[i].dkl_nblk = 771 label->dkl_vtoc.v_part[i].p_size; 772 #else 773 #error No VTOC format defined. 774 #endif /* defined(_SUNOS_VTOC_8) */ 775 } 776 777 /* 778 * Use the VTOC if valid, or install a default 779 */ 780 if (label->dkl_vtoc.v_version == V_VERSION) { 781 (void) memcpy(disk_info->v_volume, label->dkl_vtoc.v_volume, 782 LEN_DKL_VVOL); 783 part->vtoc = label->dkl_vtoc; 784 } else { 785 (void) memset(disk_info->v_volume, 0, LEN_DKL_VVOL); 786 set_vtoc_defaults(part); 787 } 788 789 /* 790 * Link the disk to the partition map 791 */ 792 disk_info->disk_parts = part; 793 794 return (disk); 795 } 796 797 /* 798 * Get a disk type that has label info. This is used to convert 799 * EFI label to SMI label 800 */ 801 struct disk_type * 802 auto_direct_get_geom_label(int fd, struct dk_label *label) 803 { 804 struct disk_type *disk_type; 805 806 if (auto_label_init(label) != 0) { 807 err_print("auto_direct_get_geom_label: failed to get label" 808 "geometry"); 809 return (NULL); 810 } else { 811 disk_type = new_direct_disk_type(fd, "DEFAULT", label); 812 return (disk_type); 813 } 814 } 815 816 /* 817 * Auto-sense a scsi disk configuration, ie get the information 818 * necessary to construct a label. We have two different 819 * ways to auto-sense a scsi disk: 820 * - format.dat override, via inquiry name 821 * - generic scsi, via standard mode sense and inquiry 822 * Depending on how and when we are called, and/or 823 * change geometry and reformat. 824 */ 825 struct disk_type * 826 auto_sense( 827 int fd, 828 int can_prompt, 829 struct dk_label *label) 830 { 831 struct scsi_inquiry inquiry; 832 struct scsi_capacity_16 capacity; 833 struct disk_type *disk_type; 834 char disk_name[DISK_NAME_MAX]; 835 int force_format_dat = 0; 836 int force_generic = 0; 837 u_ioparam_t ioparam; 838 int deflt; 839 840 /* 841 * First, if expert mode, find out if the user 842 * wants to override any of the standard methods. 843 */ 844 if (can_prompt && expert_mode) { 845 deflt = 1; 846 ioparam.io_charlist = confirm_list; 847 if (input(FIO_MSTR, FORMAT_MSG, '?', &ioparam, 848 &deflt, DATA_INPUT) == 0) { 849 force_format_dat = 1; 850 } else if (input(FIO_MSTR, GENERIC_MSG, '?', &ioparam, 851 &deflt, DATA_INPUT) == 0) { 852 force_generic = 1; 853 } 854 } 855 856 /* 857 * Get the Inquiry data. If this fails, there's 858 * no hope for this disk, so give up. 859 */ 860 if (uscsi_inquiry(fd, (char *)&inquiry, sizeof (inquiry))) { 861 return ((struct disk_type *)NULL); 862 } 863 if (option_msg && diag_msg) { 864 err_print("Product id: "); 865 print_buf(inquiry.inq_pid, sizeof (inquiry.inq_pid)); 866 err_print("\n"); 867 } 868 869 /* 870 * Get the Read Capacity 871 */ 872 if (uscsi_read_capacity(fd, &capacity)) { 873 return ((struct disk_type *)NULL); 874 } 875 876 /* 877 * If the reported capacity is set to zero, then the disk 878 * is not usable. If the reported capacity is set to all 879 * 0xf's, then this disk is too large. These could only 880 * happen with a device that supports LBAs larger than 64 881 * bits which are not defined by any current T10 standards 882 * or by error responding from target. 883 */ 884 if ((capacity.sc_capacity == 0) || 885 (capacity.sc_capacity == UINT_MAX64)) { 886 if (option_msg && diag_msg) { 887 err_print("Invalid capacity\n"); 888 } 889 return ((struct disk_type *)NULL); 890 } 891 if (option_msg && diag_msg) { 892 err_print("blocks: %llu (0x%llx)\n", 893 capacity.sc_capacity, capacity.sc_capacity); 894 err_print("blksize: %u\n", capacity.sc_lbasize); 895 } 896 897 /* 898 * Extract the disk name for the format.dat override 899 */ 900 (void) get_sun_disk_name(disk_name, &inquiry); 901 if (option_msg && diag_msg) { 902 err_print("disk name: `%s`\n", disk_name); 903 } 904 905 /* 906 * Figure out which method we use for auto sense. 907 * If a particular method fails, we fall back to 908 * the next possibility. 909 */ 910 911 if (force_generic) { 912 return (generic_disk_sense(fd, can_prompt, label, 913 &inquiry, &capacity, disk_name)); 914 } 915 916 /* 917 * Try for an existing format.dat first 918 */ 919 if ((disk_type = find_scsi_disk_by_name(disk_name)) != NULL) { 920 if (use_existing_disk_type(fd, can_prompt, label, 921 &inquiry, disk_type, &capacity)) { 922 return (disk_type); 923 } 924 if (force_format_dat) { 925 return (NULL); 926 } 927 } 928 929 /* 930 * Otherwise, try using generic SCSI-2 sense and inquiry. 931 */ 932 933 return (generic_disk_sense(fd, can_prompt, label, 934 &inquiry, &capacity, disk_name)); 935 } 936 937 938 939 /*ARGSUSED*/ 940 static struct disk_type * 941 generic_disk_sense( 942 int fd, 943 int can_prompt, 944 struct dk_label *label, 945 struct scsi_inquiry *inquiry, 946 struct scsi_capacity_16 *capacity, 947 char *disk_name) 948 { 949 struct disk_type *disk; 950 int setdefault = 0; 951 uint_t pcyl = 0; 952 uint_t ncyl = 0; 953 uint_t acyl = 0; 954 uint_t nhead = 0; 955 uint_t nsect = 0; 956 int rpm = 0; 957 diskaddr_t nblocks = 0; 958 diskaddr_t tblocks = 0; 959 union { 960 struct mode_format page3; 961 uchar_t buf3[MAX_MODE_SENSE_SIZE]; 962 } u_page3; 963 union { 964 struct mode_geometry page4; 965 uchar_t buf4[MAX_MODE_SENSE_SIZE]; 966 } u_page4; 967 struct scsi_capacity_16 new_capacity; 968 struct mode_format *page3 = &u_page3.page3; 969 struct mode_geometry *page4 = &u_page4.page4; 970 struct scsi_ms_header header; 971 972 /* 973 * If the name of this disk appears to be "SUN", use it, 974 * otherwise construct a name out of the generic 975 * Inquiry info. If it turns out that we already 976 * have a SUN disk type of this name that differs 977 * in geometry, we will revert to the generic name 978 * anyway. 979 */ 980 if (memcmp(disk_name, "SUN", strlen("SUN")) != 0) { 981 (void) get_generic_disk_name(disk_name, inquiry); 982 } 983 984 /* 985 * If the device's block size is not 512, we have to 986 * change block size, reformat, and then sense the 987 * geometry. To do this, we must be able to prompt 988 * the user. 989 */ 990 if (capacity->sc_lbasize != DEV_BSIZE) { 991 if (!can_prompt) { 992 return (NULL); 993 } 994 if (force_blocksize(fd)) { 995 goto err; 996 } 997 998 /* 999 * Get the capacity again, since this has changed 1000 */ 1001 if (uscsi_read_capacity(fd, &new_capacity)) { 1002 goto err; 1003 } 1004 if (option_msg && diag_msg) { 1005 err_print("blocks: %llu (0x%llx)\n", 1006 new_capacity.sc_capacity, 1007 new_capacity.sc_capacity); 1008 err_print("blksize: %u\n", new_capacity.sc_lbasize); 1009 } 1010 capacity = &new_capacity; 1011 if (capacity->sc_lbasize != DEV_BSIZE) { 1012 goto err; 1013 } 1014 } 1015 1016 /* 1017 * Get the number of blocks from Read Capacity data. Note that 1018 * the logical block address range from 0 to capacity->sc_capacity. 1019 * Limit the size to 2 TB (UINT32_MAX) to use with SMI labels. 1020 */ 1021 tblocks = (capacity->sc_capacity + 1); 1022 if (tblocks > UINT32_MAX) 1023 nblocks = UINT32_MAX; 1024 else 1025 nblocks = tblocks; 1026 1027 /* 1028 * Get current Page 3 - Format Parameters page 1029 */ 1030 if (uscsi_mode_sense(fd, DAD_MODE_FORMAT, MODE_SENSE_PC_CURRENT, 1031 (caddr_t)&u_page3, MAX_MODE_SENSE_SIZE, &header)) { 1032 setdefault = 1; 1033 } 1034 1035 /* 1036 * Get current Page 4 - Drive Geometry page 1037 */ 1038 if (uscsi_mode_sense(fd, DAD_MODE_GEOMETRY, MODE_SENSE_PC_CURRENT, 1039 (caddr_t)&u_page4, MAX_MODE_SENSE_SIZE, &header)) { 1040 setdefault = 1; 1041 } 1042 1043 if (setdefault != 1) { 1044 /* The inquiry of mode page 3 & page 4 are successful */ 1045 /* 1046 * Correct for byte order if necessary 1047 */ 1048 page4->rpm = BE_16(page4->rpm); 1049 page4->step_rate = BE_16(page4->step_rate); 1050 page3->tracks_per_zone = BE_16(page3->tracks_per_zone); 1051 page3->alt_sect_zone = BE_16(page3->alt_sect_zone); 1052 page3->alt_tracks_zone = BE_16(page3->alt_tracks_zone); 1053 page3->alt_tracks_vol = BE_16(page3->alt_tracks_vol); 1054 page3->sect_track = BE_16(page3->sect_track); 1055 page3->data_bytes_sect = BE_16(page3->data_bytes_sect); 1056 page3->interleave = BE_16(page3->interleave); 1057 page3->track_skew = BE_16(page3->track_skew); 1058 page3->cylinder_skew = BE_16(page3->cylinder_skew); 1059 1060 1061 /* 1062 * Construct a new label out of the sense data, 1063 * Inquiry and Capacity. 1064 * 1065 * If the disk capacity is > 1TB then simply compute 1066 * the CHS values based on the total disk capacity and 1067 * not use the values from mode-sense data. 1068 */ 1069 if (tblocks > INT32_MAX) { 1070 compute_chs_values(tblocks, nblocks, &pcyl, &nhead, 1071 &nsect); 1072 } else { 1073 pcyl = (page4->cyl_ub << 16) + (page4->cyl_mb << 8) + 1074 page4->cyl_lb; 1075 nhead = page4->heads; 1076 nsect = page3->sect_track; 1077 } 1078 1079 rpm = page4->rpm; 1080 1081 /* 1082 * If the number of physical cylinders reported is less 1083 * the SUN_MIN_CYL(3) then try to adjust the geometry so that 1084 * we have atleast SUN_MIN_CYL cylinders. 1085 */ 1086 if (pcyl < SUN_MIN_CYL) { 1087 if (nhead == 0 || nsect == 0) { 1088 setdefault = 1; 1089 } else if (adjust_disk_geometry( 1090 (diskaddr_t)(capacity->sc_capacity + 1), 1091 &pcyl, &nhead, &nsect)) { 1092 setdefault = 1; 1093 } 1094 } 1095 } 1096 1097 if (setdefault == 1) { 1098 /* 1099 * If the number of cylinders or the number of heads reported 1100 * is zero, we think the inquiry of page 3 and page 4 failed. 1101 * We will set the geometry infomation by ourselves. 1102 */ 1103 compute_chs_values(tblocks, nblocks, &pcyl, &nhead, &nsect); 1104 } 1105 1106 /* 1107 * The sd driver reserves 2 cylinders the backup disk label and 1108 * the deviceid. Set the number of data cylinders to pcyl-acyl. 1109 */ 1110 acyl = DK_ACYL; 1111 ncyl = pcyl - acyl; 1112 1113 if (option_msg && diag_msg) { 1114 err_print("Geometry:\n"); 1115 err_print(" pcyl: %u\n", pcyl); 1116 err_print(" ncyl: %u\n", ncyl); 1117 err_print(" heads: %u\n", nhead); 1118 err_print(" nsects: %u\n", nsect); 1119 err_print(" acyl: %u\n", acyl); 1120 1121 #if defined(_SUNOS_VTOC_16) 1122 err_print(" bcyl: %u\n", bcyl); 1123 #endif /* defined(_SUNOS_VTOC_16) */ 1124 1125 err_print(" rpm: %d\n", rpm); 1126 err_print(" nblocks: %llu\n", nblocks); 1127 } 1128 1129 /* 1130 * Some drives do not support page4 or report 0 for page4->rpm, 1131 * adjust it to AVG_RPM, 3600. 1132 */ 1133 if (rpm < MIN_RPM || rpm > MAX_RPM) { 1134 err_print("The current rpm value %d is invalid," 1135 " adjusting it to %d\n", rpm, AVG_RPM); 1136 rpm = AVG_RPM; 1137 } 1138 1139 /* 1140 * Some drives report 0 for nsect (page 3, byte 10 and 11) if they 1141 * have variable number of sectors per track. So adjust nsect. 1142 * Also the value is defined as vendor specific, hence check if 1143 * it is in a tolerable range. The values (32 and 4 below) are 1144 * chosen so that this change below does not generate a different 1145 * geometry for currently supported sun disks. 1146 */ 1147 if ((nsect == 0) || 1148 ((diskaddr_t)pcyl * nhead * nsect) < (nblocks - nblocks/32) || 1149 ((diskaddr_t)pcyl * nhead * nsect) > (nblocks + nblocks/4)) { 1150 if (nblocks > (pcyl * nhead)) { 1151 err_print("Mode sense page(3) reports nsect value" 1152 " as %d, adjusting it to %llu\n", 1153 nsect, nblocks / (pcyl * nhead)); 1154 nsect = nblocks / (pcyl * nhead); 1155 } else { 1156 /* convert capacity to nsect * nhead * pcyl */ 1157 err_print("\nWARNING: Disk geometry is based on " 1158 "capacity data.\n\n"); 1159 compute_chs_values(tblocks, nblocks, &pcyl, &nhead, 1160 &nsect); 1161 ncyl = pcyl - acyl; 1162 if (option_msg && diag_msg) { 1163 err_print("Geometry:(after adjustment)\n"); 1164 err_print(" pcyl: %u\n", pcyl); 1165 err_print(" ncyl: %u\n", ncyl); 1166 err_print(" heads: %u\n", nhead); 1167 err_print(" nsects: %u\n", nsect); 1168 err_print(" acyl: %u\n", acyl); 1169 1170 #if defined(_SUNOS_VTOC_16) 1171 err_print(" bcyl: %u\n", bcyl); 1172 #endif 1173 1174 err_print(" rpm: %d\n", rpm); 1175 err_print(" nblocks: %llu\n", nblocks); 1176 } 1177 } 1178 } 1179 1180 /* 1181 * Some drives report their physical geometry such that 1182 * it is greater than the actual capacity. Adjust the 1183 * geometry to allow for this, so we don't run off 1184 * the end of the disk. 1185 */ 1186 if (((diskaddr_t)pcyl * nhead * nsect) > nblocks) { 1187 uint_t p = pcyl; 1188 if (option_msg && diag_msg) { 1189 err_print("Computed capacity (%llu) exceeds actual " 1190 "disk capacity (%llu)\n", 1191 (diskaddr_t)pcyl * nhead * nsect, nblocks); 1192 } 1193 do { 1194 pcyl--; 1195 } while (((diskaddr_t)pcyl * nhead * nsect) > nblocks); 1196 1197 if (can_prompt && expert_mode && !option_f) { 1198 /* 1199 * Try to adjust nsect instead of pcyl to see if we 1200 * can optimize. For compatability reasons do this 1201 * only in expert mode (refer to bug 1144812). 1202 */ 1203 uint_t n = nsect; 1204 do { 1205 n--; 1206 } while (((diskaddr_t)p * nhead * n) > nblocks); 1207 if (((diskaddr_t)p * nhead * n) > 1208 ((diskaddr_t)pcyl * nhead * nsect)) { 1209 u_ioparam_t ioparam; 1210 int deflt = 1; 1211 /* 1212 * Ask the user for a choice here. 1213 */ 1214 ioparam.io_bounds.lower = 1; 1215 ioparam.io_bounds.upper = 2; 1216 err_print("1. Capacity = %llu, with pcyl = %u " 1217 "nhead = %u nsect = %u\n", 1218 ((diskaddr_t)pcyl * nhead * nsect), 1219 pcyl, nhead, nsect); 1220 err_print("2. Capacity = %llu, with pcyl = %u " 1221 "nhead = %u nsect = %u\n", 1222 ((diskaddr_t)p * nhead * n), 1223 p, nhead, n); 1224 if (input(FIO_INT, "Select one of the above " 1225 "choices ", ':', &ioparam, 1226 &deflt, DATA_INPUT) == 2) { 1227 pcyl = p; 1228 nsect = n; 1229 } 1230 } 1231 } 1232 } 1233 1234 #if defined(_SUNOS_VTOC_8) 1235 /* 1236 * Finally, we need to make sure we don't overflow any of the 1237 * fields in our disk label. To do this we need to `square 1238 * the box' so to speak. We will lose bits here. 1239 */ 1240 1241 if ((pcyl > MAXIMUM_NO_CYLINDERS && 1242 ((nsect > MAXIMUM_NO_SECTORS) || 1243 (nhead > MAXIMUM_NO_HEADS))) || 1244 ((nsect > MAXIMUM_NO_SECTORS) && 1245 (nhead > MAXIMUM_NO_HEADS))) { 1246 err_print("This disk is too big to label. " 1247 " You will lose some blocks.\n"); 1248 } 1249 if ((pcyl > MAXIMUM_NO_CYLINDERS) || 1250 (nsect > MAXIMUM_NO_SECTORS) || 1251 (nhead > MAXIMUM_NO_HEADS)) { 1252 u_ioparam_t ioparam; 1253 int order; 1254 char msg[256]; 1255 1256 order = ((pcyl > nhead)<<2) | 1257 ((pcyl > nsect)<<1) | 1258 (nhead > nsect); 1259 switch (order) { 1260 case 0x7: /* pcyl > nhead > nsect */ 1261 nblocks = 1262 square_box(nblocks, 1263 &pcyl, MAXIMUM_NO_CYLINDERS, 1264 &nhead, MAXIMUM_NO_HEADS, 1265 &nsect, MAXIMUM_NO_SECTORS); 1266 break; 1267 case 0x6: /* pcyl > nsect > nhead */ 1268 nblocks = 1269 square_box(nblocks, 1270 &pcyl, MAXIMUM_NO_CYLINDERS, 1271 &nsect, MAXIMUM_NO_SECTORS, 1272 &nhead, MAXIMUM_NO_HEADS); 1273 break; 1274 case 0x4: /* nsect > pcyl > nhead */ 1275 nblocks = 1276 square_box(nblocks, 1277 &nsect, MAXIMUM_NO_SECTORS, 1278 &pcyl, MAXIMUM_NO_CYLINDERS, 1279 &nhead, MAXIMUM_NO_HEADS); 1280 break; 1281 case 0x0: /* nsect > nhead > pcyl */ 1282 nblocks = 1283 square_box(nblocks, 1284 &nsect, MAXIMUM_NO_SECTORS, 1285 &nhead, MAXIMUM_NO_HEADS, 1286 &pcyl, MAXIMUM_NO_CYLINDERS); 1287 break; 1288 case 0x3: /* nhead > pcyl > nsect */ 1289 nblocks = 1290 square_box(nblocks, 1291 &nhead, MAXIMUM_NO_HEADS, 1292 &pcyl, MAXIMUM_NO_CYLINDERS, 1293 &nsect, MAXIMUM_NO_SECTORS); 1294 break; 1295 case 0x1: /* nhead > nsect > pcyl */ 1296 nblocks = 1297 square_box(nblocks, 1298 &nhead, MAXIMUM_NO_HEADS, 1299 &nsect, MAXIMUM_NO_SECTORS, 1300 &pcyl, MAXIMUM_NO_CYLINDERS); 1301 break; 1302 default: 1303 /* How did we get here? */ 1304 impossible("label overflow adjustment"); 1305 1306 /* Do something useful */ 1307 nblocks = 1308 square_box(nblocks, 1309 &nhead, MAXIMUM_NO_HEADS, 1310 &nsect, MAXIMUM_NO_SECTORS, 1311 &pcyl, MAXIMUM_NO_CYLINDERS); 1312 break; 1313 } 1314 if (option_msg && diag_msg && 1315 (capacity->sc_capacity + 1 != nblocks)) { 1316 err_print("After adjusting geometry you lost" 1317 " %llu of %llu blocks.\n", 1318 (capacity->sc_capacity + 1 - nblocks), 1319 capacity->sc_capacity + 1); 1320 } 1321 while (can_prompt && expert_mode && !option_f) { 1322 int deflt = 1; 1323 1324 /* 1325 * Allow user to modify this by hand if desired. 1326 */ 1327 (void) sprintf(msg, 1328 "\nGeometry: %u heads, %u sectors %u cylinders" 1329 " result in %llu out of %llu blocks.\n" 1330 "Do you want to modify the device geometry", 1331 nhead, nsect, pcyl, 1332 nblocks, capacity->sc_capacity + 1); 1333 1334 ioparam.io_charlist = confirm_list; 1335 if (input(FIO_MSTR, msg, '?', &ioparam, 1336 &deflt, DATA_INPUT) != 0) 1337 break; 1338 1339 ioparam.io_bounds.lower = MINIMUM_NO_HEADS; 1340 ioparam.io_bounds.upper = MAXIMUM_NO_HEADS; 1341 nhead = input(FIO_INT, "Number of heads", ':', 1342 &ioparam, (int *)&nhead, DATA_INPUT); 1343 ioparam.io_bounds.lower = MINIMUM_NO_SECTORS; 1344 ioparam.io_bounds.upper = MAXIMUM_NO_SECTORS; 1345 nsect = input(FIO_INT, 1346 "Number of sectors per track", 1347 ':', &ioparam, (int *)&nsect, DATA_INPUT); 1348 ioparam.io_bounds.lower = SUN_MIN_CYL; 1349 ioparam.io_bounds.upper = MAXIMUM_NO_CYLINDERS; 1350 pcyl = input(FIO_INT, "Number of cylinders", 1351 ':', &ioparam, (int *)&pcyl, DATA_INPUT); 1352 nblocks = (diskaddr_t)nhead * nsect * pcyl; 1353 if (nblocks > capacity->sc_capacity + 1) { 1354 err_print("Warning: %llu blocks exceeds " 1355 "disk capacity of %llu blocks\n", 1356 nblocks, 1357 capacity->sc_capacity + 1); 1358 } 1359 } 1360 } 1361 #endif /* defined(_SUNOS_VTOC_8) */ 1362 1363 ncyl = pcyl - acyl; 1364 1365 if (option_msg && diag_msg) { 1366 err_print("\nGeometry after adjusting for capacity:\n"); 1367 err_print(" pcyl: %u\n", pcyl); 1368 err_print(" ncyl: %u\n", ncyl); 1369 err_print(" heads: %u\n", nhead); 1370 err_print(" nsects: %u\n", nsect); 1371 err_print(" acyl: %u\n", acyl); 1372 err_print(" rpm: %d\n", rpm); 1373 } 1374 1375 (void) memset((char *)label, 0, sizeof (struct dk_label)); 1376 1377 label->dkl_magic = DKL_MAGIC; 1378 1379 (void) snprintf(label->dkl_asciilabel, sizeof (label->dkl_asciilabel), 1380 "%s cyl %u alt %u hd %u sec %u", 1381 disk_name, ncyl, acyl, nhead, nsect); 1382 1383 label->dkl_pcyl = pcyl; 1384 label->dkl_ncyl = ncyl; 1385 label->dkl_acyl = acyl; 1386 label->dkl_nhead = nhead; 1387 label->dkl_nsect = nsect; 1388 label->dkl_apc = 0; 1389 label->dkl_intrlv = 1; 1390 label->dkl_rpm = rpm; 1391 1392 #if defined(_FIRMWARE_NEEDS_FDISK) 1393 if (auto_solaris_part(label) == -1) 1394 goto err; 1395 ncyl = label->dkl_ncyl; 1396 #endif /* defined(_FIRMWARE_NEEDS_FDISK) */ 1397 1398 1399 if (!build_default_partition(label, DKC_SCSI_CCS)) { 1400 goto err; 1401 } 1402 1403 (void) checksum(label, CK_MAKESUM); 1404 1405 /* 1406 * Find an existing disk type defined for this disk. 1407 * For this to work, both the name and geometry must 1408 * match. If there is no such type, but there already 1409 * is a disk defined with that name, but with a different 1410 * geometry, construct a new generic disk name out of 1411 * the inquiry information. Whatever name we're 1412 * finally using, if there's no such disk type defined, 1413 * build a new disk definition. 1414 */ 1415 if ((disk = find_scsi_disk_type(disk_name, label)) == NULL) { 1416 if (find_scsi_disk_by_name(disk_name) != NULL) { 1417 char old_name[DISK_NAME_MAX]; 1418 (void) strcpy(old_name, disk_name); 1419 (void) get_generic_disk_name(disk_name, 1420 inquiry); 1421 if (option_msg && diag_msg) { 1422 err_print( 1423 "Changing disk type name from '%s' to '%s'\n", old_name, disk_name); 1424 } 1425 (void) snprintf(label->dkl_asciilabel, 1426 sizeof (label->dkl_asciilabel), 1427 "%s cyl %u alt %u hd %u sec %u", 1428 disk_name, ncyl, acyl, nhead, nsect); 1429 (void) checksum(label, CK_MAKESUM); 1430 disk = find_scsi_disk_type(disk_name, label); 1431 } 1432 if (disk == NULL) { 1433 disk = new_scsi_disk_type(fd, disk_name, label); 1434 if (disk == NULL) 1435 goto err; 1436 } 1437 } 1438 1439 return (disk); 1440 1441 err: 1442 if (option_msg && diag_msg) { 1443 err_print( 1444 "Configuration via generic SCSI-2 information failed\n"); 1445 } 1446 return (NULL); 1447 } 1448 1449 1450 /*ARGSUSED*/ 1451 static int 1452 use_existing_disk_type( 1453 int fd, 1454 int can_prompt, 1455 struct dk_label *label, 1456 struct scsi_inquiry *inquiry, 1457 struct disk_type *disk_type, 1458 struct scsi_capacity_16 *capacity) 1459 { 1460 struct scsi_capacity_16 new_capacity; 1461 int pcyl; 1462 int acyl; 1463 int nhead; 1464 int nsect; 1465 int rpm; 1466 1467 /* 1468 * If the device's block size is not 512, we have to 1469 * change block size, reformat, and then sense the 1470 * geometry. To do this, we must be able to prompt 1471 * the user. 1472 */ 1473 if (capacity->sc_lbasize != DEV_BSIZE) { 1474 if (!can_prompt) { 1475 return (0); 1476 } 1477 if (force_blocksize(fd)) { 1478 goto err; 1479 } 1480 1481 /* 1482 * Get the capacity again, since this has changed 1483 */ 1484 if (uscsi_read_capacity(fd, &new_capacity)) { 1485 goto err; 1486 } 1487 1488 if (option_msg && diag_msg) { 1489 err_print("blocks: %llu (0x%llx)\n", 1490 new_capacity.sc_capacity, 1491 new_capacity.sc_capacity); 1492 err_print("blksize: %u\n", new_capacity.sc_lbasize); 1493 } 1494 1495 capacity = &new_capacity; 1496 if (capacity->sc_lbasize != DEV_BSIZE) { 1497 goto err; 1498 } 1499 } 1500 1501 /* 1502 * Construct a new label out of the format.dat 1503 */ 1504 pcyl = disk_type->dtype_pcyl; 1505 acyl = disk_type->dtype_acyl; 1506 ncyl = disk_type->dtype_ncyl; 1507 nhead = disk_type->dtype_nhead; 1508 nsect = disk_type->dtype_nsect; 1509 rpm = disk_type->dtype_rpm; 1510 1511 if (option_msg && diag_msg) { 1512 err_print("Format.dat geometry:\n"); 1513 err_print(" pcyl: %u\n", pcyl); 1514 err_print(" heads: %u\n", nhead); 1515 err_print(" nsects: %u\n", nsect); 1516 err_print(" acyl: %u\n", acyl); 1517 err_print(" rpm: %d\n", rpm); 1518 } 1519 1520 (void) memset((char *)label, 0, sizeof (struct dk_label)); 1521 1522 label->dkl_magic = DKL_MAGIC; 1523 1524 (void) snprintf(label->dkl_asciilabel, sizeof (label->dkl_asciilabel), 1525 "%s cyl %u alt %u hd %u sec %u", 1526 disk_type->dtype_asciilabel, 1527 ncyl, acyl, nhead, nsect); 1528 1529 label->dkl_pcyl = pcyl; 1530 label->dkl_ncyl = ncyl; 1531 label->dkl_acyl = acyl; 1532 label->dkl_nhead = nhead; 1533 label->dkl_nsect = nsect; 1534 label->dkl_apc = 0; 1535 label->dkl_intrlv = 1; 1536 label->dkl_rpm = rpm; 1537 1538 if (!build_default_partition(label, DKC_SCSI_CCS)) { 1539 goto err; 1540 } 1541 1542 (void) checksum(label, CK_MAKESUM); 1543 return (1); 1544 1545 err: 1546 if (option_msg && diag_msg) { 1547 err_print( 1548 "Configuration via format.dat geometry failed\n"); 1549 } 1550 return (0); 1551 } 1552 1553 int 1554 build_default_partition( 1555 struct dk_label *label, 1556 int ctrl_type) 1557 { 1558 int i; 1559 int ncyls[NDKMAP]; 1560 diskaddr_t nblks; 1561 int cyl; 1562 struct dk_vtoc *vtoc; 1563 struct part_table *pt; 1564 struct default_partitions *dpt; 1565 diskaddr_t capacity; 1566 int freecyls; 1567 int blks_per_cyl; 1568 int ncyl; 1569 1570 #ifdef lint 1571 ctrl_type = ctrl_type; 1572 #endif 1573 1574 /* 1575 * Install a default vtoc 1576 */ 1577 vtoc = &label->dkl_vtoc; 1578 vtoc->v_version = V_VERSION; 1579 vtoc->v_nparts = NDKMAP; 1580 vtoc->v_sanity = VTOC_SANE; 1581 1582 for (i = 0; i < NDKMAP; i++) { 1583 vtoc->v_part[i].p_tag = default_vtoc_map[i].p_tag; 1584 vtoc->v_part[i].p_flag = default_vtoc_map[i].p_flag; 1585 } 1586 1587 /* 1588 * Find a partition that matches this disk. Capacity 1589 * is in integral number of megabytes. 1590 */ 1591 capacity = ((diskaddr_t)(label->dkl_ncyl) * label->dkl_nhead * 1592 label->dkl_nsect) / (1024 * 1024) / DEV_BSIZE; 1593 dpt = default_partitions; 1594 for (i = 0; i < DEFAULT_PARTITION_TABLE_SIZE; i++, dpt++) { 1595 if (capacity >= dpt->min_capacity && 1596 capacity < dpt->max_capacity) { 1597 break; 1598 } 1599 } 1600 if (i == DEFAULT_PARTITION_TABLE_SIZE) { 1601 if (option_msg && diag_msg) { 1602 err_print("No matching default partition (%llu)\n", 1603 capacity); 1604 } 1605 return (0); 1606 } 1607 pt = dpt->part_table; 1608 1609 /* 1610 * Go through default partition table, finding fixed 1611 * sized entries. 1612 */ 1613 freecyls = label->dkl_ncyl; 1614 blks_per_cyl = label->dkl_nhead * label->dkl_nsect; 1615 for (i = 0; i < NDKMAP; i++) { 1616 if (pt->partitions[i] == HOG || pt->partitions[i] == 0) { 1617 ncyls[i] = 0; 1618 } else { 1619 /* 1620 * Calculate number of cylinders necessary 1621 * for specified size, rounding up to 1622 * the next greatest integral number of 1623 * cylinders. Always give what they 1624 * asked or more, never less. 1625 */ 1626 nblks = pt->partitions[i] * ((1024*1024)/DEV_BSIZE); 1627 nblks += (blks_per_cyl - 1); 1628 ncyls[i] = nblks / blks_per_cyl; 1629 freecyls -= ncyls[i]; 1630 } 1631 } 1632 1633 if (freecyls < 0) { 1634 if (option_msg && diag_msg) { 1635 for (i = 0; i < NDKMAP; i++) { 1636 if (ncyls[i] == 0) 1637 continue; 1638 err_print("Partition %d: %u cyls\n", 1639 i, ncyls[i]); 1640 } 1641 err_print("Free cylinders exhausted (%d)\n", 1642 freecyls); 1643 } 1644 return (0); 1645 } 1646 #if defined(i386) 1647 /* 1648 * Set the default boot partition to 1 cylinder 1649 */ 1650 ncyls[8] = 1; 1651 freecyls -= 1; 1652 1653 /* 1654 * If current disk type is not a SCSI disk, 1655 * set the default alternates partition to 2 cylinders 1656 */ 1657 if (ctrl_type != DKC_SCSI_CCS) { 1658 ncyls[9] = 2; 1659 freecyls -= 2; 1660 } 1661 #endif /* defined(i386) */ 1662 1663 /* 1664 * Set the free hog partition to whatever space remains. 1665 * It's an error to have more than one HOG partition, 1666 * but we don't verify that here. 1667 */ 1668 for (i = 0; i < NDKMAP; i++) { 1669 if (pt->partitions[i] == HOG) { 1670 assert(ncyls[i] == 0); 1671 ncyls[i] = freecyls; 1672 break; 1673 } 1674 } 1675 1676 /* 1677 * Error checking 1678 */ 1679 ncyl = 0; 1680 for (i = 0; i < NDKMAP; i++) { 1681 ncyl += ncyls[i]; 1682 } 1683 assert(ncyl == (label->dkl_ncyl)); 1684 1685 /* 1686 * Finally, install the partition in the label. 1687 */ 1688 cyl = 0; 1689 1690 #if defined(_SUNOS_VTOC_16) 1691 for (i = NDKMAP/2; i < NDKMAP; i++) { 1692 if (i == 2 || ncyls[i] == 0) 1693 continue; 1694 label->dkl_vtoc.v_part[i].p_start = cyl * blks_per_cyl; 1695 label->dkl_vtoc.v_part[i].p_size = ncyls[i] * blks_per_cyl; 1696 cyl += ncyls[i]; 1697 } 1698 for (i = 0; i < NDKMAP/2; i++) { 1699 1700 #elif defined(_SUNOS_VTOC_8) 1701 for (i = 0; i < NDKMAP; i++) { 1702 1703 #else 1704 #error No VTOC format defined. 1705 #endif /* defined(_SUNOS_VTOC_16) */ 1706 1707 if (i == 2 || ncyls[i] == 0) { 1708 #if defined(_SUNOS_VTOC_8) 1709 if (i != 2) { 1710 label->dkl_map[i].dkl_cylno = 0; 1711 label->dkl_map[i].dkl_nblk = 0; 1712 } 1713 #endif 1714 continue; 1715 } 1716 #if defined(_SUNOS_VTOC_8) 1717 label->dkl_map[i].dkl_cylno = cyl; 1718 label->dkl_map[i].dkl_nblk = ncyls[i] * blks_per_cyl; 1719 #elif defined(_SUNOS_VTOC_16) 1720 label->dkl_vtoc.v_part[i].p_start = cyl * blks_per_cyl; 1721 label->dkl_vtoc.v_part[i].p_size = ncyls[i] * blks_per_cyl; 1722 1723 #else 1724 #error No VTOC format defined. 1725 #endif /* defined(_SUNOS_VTOC_8) */ 1726 1727 cyl += ncyls[i]; 1728 } 1729 1730 /* 1731 * Set the whole disk partition 1732 */ 1733 #if defined(_SUNOS_VTOC_8) 1734 label->dkl_map[2].dkl_cylno = 0; 1735 label->dkl_map[2].dkl_nblk = 1736 label->dkl_ncyl * label->dkl_nhead * label->dkl_nsect; 1737 1738 #elif defined(_SUNOS_VTOC_16) 1739 label->dkl_vtoc.v_part[2].p_start = 0; 1740 label->dkl_vtoc.v_part[2].p_size = 1741 (label->dkl_ncyl + label->dkl_acyl) * label->dkl_nhead * 1742 label->dkl_nsect; 1743 #else 1744 #error No VTOC format defined. 1745 #endif /* defined(_SUNOS_VTOC_8) */ 1746 1747 1748 if (option_msg && diag_msg) { 1749 float scaled; 1750 err_print("\n"); 1751 for (i = 0; i < NDKMAP; i++) { 1752 #if defined(_SUNOS_VTOC_8) 1753 if (label->dkl_map[i].dkl_nblk == 0) 1754 1755 #elif defined(_SUNOS_VTOC_16) 1756 if (label->dkl_vtoc.v_part[i].p_size == 0) 1757 1758 #else 1759 #error No VTOC format defined. 1760 #endif /* defined(_SUNOS_VTOC_8) */ 1761 1762 continue; 1763 err_print("Partition %d: ", i); 1764 #if defined(_SUNOS_VTOC_8) 1765 scaled = bn2mb(label->dkl_map[i].dkl_nblk); 1766 1767 #elif defined(_SUNOS_VTOC_16) 1768 1769 scaled = bn2mb(label->dkl_vtoc.v_part[i].p_size); 1770 #else 1771 #error No VTOC format defined. 1772 #endif /* defined(_SUNOS_VTOC_8) */ 1773 1774 if (scaled > 1024.0) { 1775 err_print("%6.2fGB ", scaled/1024.0); 1776 } else { 1777 err_print("%6.2fMB ", scaled); 1778 } 1779 err_print(" %6d cylinders\n", 1780 #if defined(_SUNOS_VTOC_8) 1781 label->dkl_map[i].dkl_nblk/blks_per_cyl); 1782 1783 #elif defined(_SUNOS_VTOC_16) 1784 label->dkl_vtoc.v_part[i].p_size/blks_per_cyl); 1785 1786 #else 1787 #error No VTOC format defined. 1788 #endif /* defined(_SUNOS_VTOC_8) */ 1789 1790 } 1791 err_print("\n"); 1792 } 1793 1794 return (1); 1795 } 1796 1797 1798 1799 /* 1800 * Find an existing scsi disk definition by this name, 1801 * if possible. 1802 */ 1803 static struct disk_type * 1804 find_scsi_disk_type( 1805 char *disk_name, 1806 struct dk_label *label) 1807 { 1808 struct ctlr_type *ctlr; 1809 struct disk_type *dp; 1810 1811 ctlr = find_scsi_ctlr_type(); 1812 for (dp = ctlr->ctype_dlist; dp != NULL; dp = dp->dtype_next) { 1813 if (dp->dtype_asciilabel) { 1814 if ((strcmp(dp->dtype_asciilabel, disk_name) == 0) && 1815 dp->dtype_pcyl == label->dkl_pcyl && 1816 dp->dtype_ncyl == label->dkl_ncyl && 1817 dp->dtype_acyl == label->dkl_acyl && 1818 dp->dtype_nhead == label->dkl_nhead && 1819 dp->dtype_nsect == label->dkl_nsect) { 1820 return (dp); 1821 } 1822 } 1823 } 1824 1825 return ((struct disk_type *)NULL); 1826 } 1827 1828 1829 /* 1830 * Find an existing scsi disk definition by this name, 1831 * if possible. 1832 */ 1833 static struct disk_type * 1834 find_scsi_disk_by_name( 1835 char *disk_name) 1836 { 1837 struct ctlr_type *ctlr; 1838 struct disk_type *dp; 1839 1840 ctlr = find_scsi_ctlr_type(); 1841 for (dp = ctlr->ctype_dlist; dp != NULL; dp = dp->dtype_next) { 1842 if (dp->dtype_asciilabel) { 1843 if ((strcmp(dp->dtype_asciilabel, disk_name) == 0)) { 1844 return (dp); 1845 } 1846 } 1847 } 1848 1849 return ((struct disk_type *)NULL); 1850 } 1851 1852 1853 /* 1854 * Return a pointer to the ctlr_type structure for SCSI 1855 * disks. This list is built into the program, so there's 1856 * no chance of not being able to find it, unless someone 1857 * totally mangles the code. 1858 */ 1859 static struct ctlr_type * 1860 find_scsi_ctlr_type() 1861 { 1862 struct mctlr_list *mlp; 1863 1864 mlp = controlp; 1865 1866 while (mlp != NULL) { 1867 if (mlp->ctlr_type->ctype_ctype == DKC_SCSI_CCS) { 1868 return (mlp->ctlr_type); 1869 } 1870 mlp = mlp->next; 1871 } 1872 1873 impossible("no SCSI controller type"); 1874 1875 return ((struct ctlr_type *)NULL); 1876 } 1877 1878 1879 1880 /* 1881 * Return a pointer to the scsi ctlr_info structure. This 1882 * structure is allocated the first time format sees a 1883 * disk on this controller, so it must be present. 1884 */ 1885 static struct ctlr_info * 1886 find_scsi_ctlr_info( 1887 struct dk_cinfo *dkinfo) 1888 { 1889 struct ctlr_info *ctlr; 1890 1891 if (dkinfo->dki_ctype != DKC_SCSI_CCS) { 1892 return (NULL); 1893 } 1894 1895 for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) { 1896 if (ctlr->ctlr_addr == dkinfo->dki_addr && 1897 ctlr->ctlr_space == dkinfo->dki_space && 1898 ctlr->ctlr_ctype->ctype_ctype == DKC_SCSI_CCS) { 1899 return (ctlr); 1900 } 1901 } 1902 1903 impossible("no SCSI controller info"); 1904 1905 return ((struct ctlr_info *)NULL); 1906 } 1907 1908 1909 1910 static struct disk_type * 1911 new_scsi_disk_type( 1912 int fd, 1913 char *disk_name, 1914 struct dk_label *label) 1915 { 1916 struct disk_type *dp; 1917 struct disk_type *disk; 1918 struct ctlr_info *ctlr; 1919 struct dk_cinfo dkinfo; 1920 struct partition_info *part; 1921 struct partition_info *pt; 1922 struct disk_info *disk_info; 1923 int i; 1924 1925 /* 1926 * Get the disk controller info for this disk 1927 */ 1928 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { 1929 if (option_msg && diag_msg) { 1930 err_print("DKIOCINFO failed\n"); 1931 } 1932 return (NULL); 1933 } 1934 1935 /* 1936 * Find the ctlr_info for this disk. 1937 */ 1938 ctlr = find_scsi_ctlr_info(&dkinfo); 1939 1940 /* 1941 * Allocate a new disk type for the SCSI controller. 1942 */ 1943 disk = (struct disk_type *)zalloc(sizeof (struct disk_type)); 1944 1945 /* 1946 * Find the disk_info instance for this disk. 1947 */ 1948 disk_info = find_scsi_disk_info(&dkinfo); 1949 1950 /* 1951 * The controller and the disk should match. 1952 */ 1953 assert(disk_info->disk_ctlr == ctlr); 1954 1955 /* 1956 * Link the disk into the list of disks 1957 */ 1958 dp = ctlr->ctlr_ctype->ctype_dlist; 1959 if (dp == NULL) { 1960 ctlr->ctlr_ctype->ctype_dlist = disk; 1961 } else { 1962 while (dp->dtype_next != NULL) { 1963 dp = dp->dtype_next; 1964 } 1965 dp->dtype_next = disk; 1966 } 1967 disk->dtype_next = NULL; 1968 1969 /* 1970 * Allocate and initialize the disk name. 1971 */ 1972 disk->dtype_asciilabel = alloc_string(disk_name); 1973 1974 /* 1975 * Initialize disk geometry info 1976 */ 1977 disk->dtype_pcyl = label->dkl_pcyl; 1978 disk->dtype_ncyl = label->dkl_ncyl; 1979 disk->dtype_acyl = label->dkl_acyl; 1980 disk->dtype_nhead = label->dkl_nhead; 1981 disk->dtype_nsect = label->dkl_nsect; 1982 disk->dtype_rpm = label->dkl_rpm; 1983 1984 /* 1985 * Attempt to match the partition map in the label 1986 * with a know partition for this disk type. 1987 */ 1988 for (part = disk->dtype_plist; part; part = part->pinfo_next) { 1989 if (parts_match(label, part)) { 1990 break; 1991 } 1992 } 1993 1994 /* 1995 * If no match was made, we need to create a partition 1996 * map for this disk. 1997 */ 1998 if (part == NULL) { 1999 part = (struct partition_info *) 2000 zalloc(sizeof (struct partition_info)); 2001 pt = disk->dtype_plist; 2002 if (pt == NULL) { 2003 disk->dtype_plist = part; 2004 } else { 2005 while (pt->pinfo_next != NULL) { 2006 pt = pt->pinfo_next; 2007 } 2008 pt->pinfo_next = part; 2009 } 2010 part->pinfo_next = NULL; 2011 2012 /* 2013 * Set up the partition name 2014 */ 2015 part->pinfo_name = alloc_string("default"); 2016 2017 /* 2018 * Fill in the partition info from the label 2019 */ 2020 for (i = 0; i < NDKMAP; i++) { 2021 2022 #if defined(_SUNOS_VTOC_8) 2023 part->pinfo_map[i] = label->dkl_map[i]; 2024 2025 #elif defined(_SUNOS_VTOC_16) 2026 part->pinfo_map[i].dkl_cylno = 2027 label->dkl_vtoc.v_part[i].p_start / 2028 ((blkaddr32_t)(disk->dtype_nhead * 2029 disk->dtype_nsect - apc)); 2030 part->pinfo_map[i].dkl_nblk = 2031 label->dkl_vtoc.v_part[i].p_size; 2032 #else 2033 #error No VTOC format defined. 2034 #endif /* defined(_SUNOS_VTOC_8) */ 2035 2036 } 2037 } 2038 2039 2040 /* 2041 * Use the VTOC if valid, or install a default 2042 */ 2043 if (label->dkl_vtoc.v_version == V_VERSION) { 2044 (void) memcpy(disk_info->v_volume, label->dkl_vtoc.v_volume, 2045 LEN_DKL_VVOL); 2046 part->vtoc = label->dkl_vtoc; 2047 } else { 2048 (void) memset(disk_info->v_volume, 0, LEN_DKL_VVOL); 2049 set_vtoc_defaults(part); 2050 } 2051 2052 /* 2053 * Link the disk to the partition map 2054 */ 2055 disk_info->disk_parts = part; 2056 2057 return (disk); 2058 } 2059 2060 2061 /* 2062 * Delete a disk type from disk type list. 2063 */ 2064 int 2065 delete_disk_type( 2066 struct disk_type *disk_type) 2067 { 2068 struct ctlr_type *ctlr; 2069 struct disk_type *dp, *disk; 2070 2071 if (cur_ctype->ctype_ctype == DKC_DIRECT) 2072 ctlr = find_direct_ctlr_type(); 2073 else if (cur_ctype->ctype_ctype == DKC_VBD) 2074 ctlr = find_vbd_ctlr_type(); 2075 else 2076 ctlr = find_scsi_ctlr_type(); 2077 if (ctlr == NULL || ctlr->ctype_dlist == NULL) { 2078 return (-1); 2079 } 2080 2081 disk = ctlr->ctype_dlist; 2082 if (disk == disk_type) { 2083 ctlr->ctype_dlist = disk->dtype_next; 2084 if (cur_label == L_TYPE_EFI) 2085 free(disk->dtype_plist->etoc); 2086 free(disk->dtype_plist); 2087 free(disk); 2088 return (0); 2089 } else { 2090 for (dp = disk->dtype_next; dp != NULL; 2091 disk = disk->dtype_next, dp = dp->dtype_next) { 2092 if (dp == disk_type) { 2093 disk->dtype_next = dp->dtype_next; 2094 if (cur_label == L_TYPE_EFI) 2095 free(dp->dtype_plist->etoc); 2096 free(dp->dtype_plist); 2097 free(dp); 2098 return (0); 2099 } 2100 } 2101 return (-1); 2102 } 2103 } 2104 2105 2106 static struct disk_info * 2107 find_scsi_disk_info( 2108 struct dk_cinfo *dkinfo) 2109 { 2110 struct disk_info *disk; 2111 struct dk_cinfo *dp; 2112 2113 for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 2114 assert(dkinfo->dki_ctype == DKC_SCSI_CCS); 2115 dp = &disk->disk_dkinfo; 2116 if (dp->dki_ctype == dkinfo->dki_ctype && 2117 dp->dki_cnum == dkinfo->dki_cnum && 2118 dp->dki_unit == dkinfo->dki_unit && 2119 strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) { 2120 return (disk); 2121 } 2122 } 2123 2124 impossible("No SCSI disk info instance\n"); 2125 2126 return ((struct disk_info *)NULL); 2127 } 2128 2129 2130 static char * 2131 get_sun_disk_name( 2132 char *disk_name, 2133 struct scsi_inquiry *inquiry) 2134 { 2135 /* 2136 * Extract the sun name of the disk 2137 */ 2138 (void) memset(disk_name, 0, DISK_NAME_MAX); 2139 (void) memcpy(disk_name, (char *)&inquiry->inq_pid[9], 7); 2140 2141 return (disk_name); 2142 } 2143 2144 2145 static char * 2146 get_generic_disk_name( 2147 char *disk_name, 2148 struct scsi_inquiry *inquiry) 2149 { 2150 char *p; 2151 2152 (void) memset(disk_name, 0, DISK_NAME_MAX); 2153 p = strcopy(disk_name, inquiry->inq_vid, 2154 sizeof (inquiry->inq_vid)); 2155 *p++ = '-'; 2156 p = strcopy(p, inquiry->inq_pid, sizeof (inquiry->inq_pid)); 2157 *p++ = '-'; 2158 p = strcopy(p, inquiry->inq_revision, 2159 sizeof (inquiry->inq_revision)); 2160 2161 return (disk_name); 2162 } 2163 2164 2165 2166 static int 2167 force_blocksize( 2168 int fd) 2169 { 2170 union { 2171 struct mode_format page3; 2172 uchar_t buf3[MAX_MODE_SENSE_SIZE]; 2173 } u_page3; 2174 struct mode_format *page3 = &u_page3.page3; 2175 struct scsi_ms_header header; 2176 2177 if (check("\ 2178 Must reformat device to 512-byte blocksize. Continue") == 0) { 2179 2180 /* 2181 * Get current Page 3 - Format Parameters page 2182 */ 2183 if (uscsi_mode_sense(fd, DAD_MODE_FORMAT, 2184 MODE_SENSE_PC_CURRENT, (caddr_t)&u_page3, 2185 MAX_MODE_SENSE_SIZE, &header)) { 2186 goto err; 2187 } 2188 2189 /* 2190 * Make our changes to the geometry 2191 */ 2192 header.mode_header.length = 0; 2193 header.mode_header.device_specific = 0; 2194 page3->mode_page.ps = 0; 2195 page3->data_bytes_sect = DEV_BSIZE; 2196 2197 /* 2198 * make sure that logical block size is of 2199 * DEV_BSIZE. 2200 */ 2201 header.block_descriptor.blksize_hi = (DEV_BSIZE >> 16); 2202 header.block_descriptor.blksize_mid = (DEV_BSIZE >> 8); 2203 header.block_descriptor.blksize_lo = (char)(DEV_BSIZE); 2204 /* 2205 * Select current Page 3 - Format Parameters page 2206 */ 2207 if (uscsi_mode_select(fd, DAD_MODE_FORMAT, 2208 MODE_SELECT_PF, (caddr_t)&u_page3, 2209 MODESENSE_PAGE_LEN(&u_page3), &header)) { 2210 goto err; 2211 } 2212 2213 /* 2214 * Now reformat the device 2215 */ 2216 if (raw_format(fd)) { 2217 goto err; 2218 } 2219 return (0); 2220 } 2221 2222 err: 2223 if (option_msg && diag_msg) { 2224 err_print( 2225 "Reformat device to 512-byte blocksize failed\n"); 2226 } 2227 return (1); 2228 } 2229 2230 static int 2231 raw_format( 2232 int fd) 2233 { 2234 union scsi_cdb cdb; 2235 struct uscsi_cmd ucmd; 2236 struct scsi_defect_hdr defect_hdr; 2237 2238 (void) memset((char *)&ucmd, 0, sizeof (ucmd)); 2239 (void) memset((char *)&cdb, 0, sizeof (union scsi_cdb)); 2240 (void) memset((char *)&defect_hdr, 0, sizeof (defect_hdr)); 2241 cdb.scc_cmd = SCMD_FORMAT; 2242 ucmd.uscsi_cdb = (caddr_t)&cdb; 2243 ucmd.uscsi_cdblen = CDB_GROUP0; 2244 ucmd.uscsi_bufaddr = (caddr_t)&defect_hdr; 2245 ucmd.uscsi_buflen = sizeof (defect_hdr); 2246 cdb.cdb_opaque[1] = FPB_DATA; 2247 2248 /* 2249 * Issue the format ioctl 2250 */ 2251 fmt_print("Formatting...\n"); 2252 (void) fflush(stdout); 2253 if (uscsi_cmd(fd, &ucmd, 2254 (option_msg && diag_msg) ? F_NORMAL : F_SILENT)) { 2255 return (1); 2256 } 2257 return (0); 2258 } 2259 2260 /* 2261 * Copy a string of characters from src to dst, for at 2262 * most n bytes. Strip all leading and trailing spaces, 2263 * and stop if there are any non-printable characters. 2264 * Return ptr to the next character to be filled. 2265 */ 2266 static char * 2267 strcopy( 2268 char *dst, 2269 char *src, 2270 int n) 2271 { 2272 int i; 2273 2274 while (*src == ' ' && n > 0) { 2275 src++; 2276 n--; 2277 } 2278 2279 for (i = 0; n-- > 0 && isascii(*src) && isprint(*src); src++) { 2280 if (*src == ' ') { 2281 i++; 2282 } else { 2283 while (i-- > 0) 2284 *dst++ = ' '; 2285 *dst++ = *src; 2286 } 2287 } 2288 2289 *dst = 0; 2290 return (dst); 2291 } 2292 2293 /* 2294 * adjust disk geometry. 2295 * This is used when disk reports a disk geometry page having 2296 * no of physical cylinders is < 3 which is the minimum required 2297 * by Solaris (2 for storing labels and at least one as a data 2298 * cylinder ) 2299 */ 2300 int 2301 adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl, uint_t *nhead, 2302 uint_t *nsect) 2303 { 2304 uint_t lcyl = *cyl; 2305 uint_t lnhead = *nhead; 2306 uint_t lnsect = *nsect; 2307 2308 assert(lcyl < SUN_MIN_CYL); 2309 2310 /* 2311 * reduce nsect by 2 for each iteration and re-calculate 2312 * the number of cylinders. 2313 */ 2314 while (lnsect > MINIMUM_NO_SECTORS && 2315 lcyl < MINIMUM_NO_CYLINDERS) { 2316 /* 2317 * make sure that we do not go below MINIMUM_NO_SECTORS. 2318 */ 2319 lnsect = max(MINIMUM_NO_SECTORS, lnsect / 2); 2320 lcyl = (capacity) / (lnhead * lnsect); 2321 } 2322 /* 2323 * If the geometry still does not satisfy 2324 * MINIMUM_NO_CYLINDERS then try to reduce the 2325 * no of heads. 2326 */ 2327 while (lnhead > MINIMUM_NO_HEADS && 2328 lcyl < MINIMUM_NO_CYLINDERS) { 2329 lnhead = max(MINIMUM_NO_HEADS, lnhead / 2); 2330 lcyl = (capacity) / (lnhead * lnsect); 2331 } 2332 /* 2333 * now we should have atleast SUN_MIN_CYL cylinders. 2334 * If we still do not get SUN_MIN_CYL with MINIMUM_NO_HEADS 2335 * and MINIMUM_NO_HEADS then return error. 2336 */ 2337 if (lcyl < SUN_MIN_CYL) 2338 return (1); 2339 else { 2340 *cyl = lcyl; 2341 *nhead = lnhead; 2342 *nsect = lnsect; 2343 return (0); 2344 } 2345 } 2346 2347 #if defined(_SUNOS_VTOC_8) 2348 /* 2349 * Reduce the size of one dimention below a specified 2350 * limit with a minimum loss of volume. Dimenstions are 2351 * assumed to be passed in form the largest value (the one 2352 * that needs to be reduced) to the smallest value. The 2353 * values will be twiddled until they are all less than or 2354 * equal to their limit. Returns the number in the new geometry. 2355 */ 2356 static diskaddr_t 2357 square_box( 2358 diskaddr_t capacity, 2359 uint_t *dim1, uint_t lim1, 2360 uint_t *dim2, uint_t lim2, 2361 uint_t *dim3, uint_t lim3) 2362 { 2363 uint_t i; 2364 2365 /* 2366 * Although the routine should work with any ordering of 2367 * parameters, it's most efficient if they are passed in 2368 * in decreasing magnitude. 2369 */ 2370 assert(*dim1 >= *dim2); 2371 assert(*dim2 >= *dim3); 2372 2373 /* 2374 * This is done in a very arbitrary manner. We could try to 2375 * find better values but I can't come up with a method that 2376 * would run in a reasonable amount of time. That could take 2377 * approximately 65535 * 65535 iterations of a dozen flops each 2378 * or well over 4G flops. 2379 * 2380 * First: 2381 * 2382 * Let's see how far we can go with bitshifts w/o losing 2383 * any blocks. 2384 */ 2385 2386 for (i = 0; (((*dim1)>>i)&1) == 0 && ((*dim1)>>i) > lim1; i++); 2387 if (i) { 2388 *dim1 = ((*dim1)>>i); 2389 *dim3 = ((*dim3)<<i); 2390 } 2391 2392 if (((*dim1) > lim1) || ((*dim2) > lim2) || ((*dim3) > lim3)) { 2393 double d[4]; 2394 2395 /* 2396 * Second: 2397 * 2398 * Set the highest value at its limit then calculate errors, 2399 * adjusting the 2nd highest value (we get better resolution 2400 * that way). 2401 */ 2402 d[1] = lim1; 2403 d[3] = *dim3; 2404 d[2] = (double)capacity/(d[1]*d[3]); 2405 2406 /* 2407 * If we overflowed the middle term, set it to its limit and 2408 * chose a new low term. 2409 */ 2410 if (d[2] > lim2) { 2411 d[2] = lim2; 2412 d[3] = (double)capacity/(d[1]*d[2]); 2413 } 2414 /* 2415 * Convert to integers. 2416 */ 2417 *dim1 = (int)d[1]; 2418 *dim2 = (int)d[2]; 2419 *dim3 = (int)d[3]; 2420 } 2421 /* 2422 * Fixup any other possible problems. 2423 * If this happens, we need a new disklabel format. 2424 */ 2425 if (*dim1 > lim1) *dim1 = lim1; 2426 if (*dim2 > lim2) *dim2 = lim2; 2427 if (*dim3 > lim3) *dim3 = lim3; 2428 return (*dim1 * *dim2 * *dim3); 2429 } 2430 #endif /* defined(_SUNOS_VTOC_8) */ 2431 2432 /* 2433 * Calculate CHS values based on the capacity data. 2434 * 2435 * NOTE: This function is same as cmlb_convert_geomerty() function in 2436 * cmlb kernel module. 2437 */ 2438 static void 2439 compute_chs_values(diskaddr_t total_capacity, diskaddr_t usable_capacity, 2440 uint_t *pcylp, uint_t *nheadp, uint_t *nsectp) 2441 { 2442 2443 /* Unlabeled SCSI floppy device */ 2444 if (total_capacity <= 0x1000) { 2445 *nheadp = 2; 2446 *pcylp = 80; 2447 *nsectp = total_capacity / (80 * 2); 2448 return; 2449 } 2450 2451 /* 2452 * For all devices we calculate cylinders using the heads and sectors 2453 * we assign based on capacity of the device. The algorithm is 2454 * designed to be compatible with the way other operating systems 2455 * lay out fdisk tables for X86 and to insure that the cylinders never 2456 * exceed 65535 to prevent problems with X86 ioctls that report 2457 * geometry. 2458 * For some smaller disk sizes we report geometry that matches those 2459 * used by X86 BIOS usage. For larger disks, we use SPT that are 2460 * multiples of 63, since other OSes that are not limited to 16-bits 2461 * for cylinders stop at 63 SPT we make do by using multiples of 63 SPT. 2462 * 2463 * The following table (in order) illustrates some end result 2464 * calculations: 2465 * 2466 * Maximum number of blocks nhead nsect 2467 * 2468 * 2097152 (1GB) 64 32 2469 * 16777216 (8GB) 128 32 2470 * 1052819775 (502.02GB) 255 63 2471 * 2105639550 (0.98TB) 255 126 2472 * 3158459325 (1.47TB) 255 189 2473 * 4211279100 (1.96TB) 255 252 2474 * 5264098875 (2.45TB) 255 315 2475 * ... 2476 */ 2477 2478 if (total_capacity <= 0x200000) { 2479 *nheadp = 64; 2480 *nsectp = 32; 2481 } else if (total_capacity <= 0x01000000) { 2482 *nheadp = 128; 2483 *nsectp = 32; 2484 } else { 2485 *nheadp = 255; 2486 2487 /* make nsect be smallest multiple of 63 */ 2488 *nsectp = ((total_capacity + 2489 (UINT16_MAX * 255 * 63) - 1) / 2490 (UINT16_MAX * 255 * 63)) * 63; 2491 2492 if (*nsectp == 0) 2493 *nsectp = (UINT16_MAX / 63) * 63; 2494 } 2495 2496 if (usable_capacity < total_capacity) 2497 *pcylp = usable_capacity / ((*nheadp) * (*nsectp)); 2498 else 2499 *pcylp = total_capacity / ((*nheadp) * (*nsectp)); 2500 } 2501