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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <ctype.h> 29 #include <dirent.h> 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <langinfo.h> 33 #include <libintl.h> 34 #include <limits.h> 35 #include <locale.h> 36 #include <stdarg.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <strings.h> 41 #include <sys/ddi.h> 42 #include <sys/mpt/mpi.h> 43 #include <sys/mpt/mpi_ioc.h> 44 #include <sys/stat.h> 45 #include <sys/types.h> 46 #include <sys/pci.h> 47 #include <unistd.h> 48 #include <sys/mnttab.h> 49 #include <sys/dkio.h> 50 #include <config_admin.h> 51 #include <sys/param.h> 52 #include <sys/raidioctl.h> 53 54 /* 55 * list of controllers to list 56 * setup like this: 57 * [ctrl_num] [status] 58 * 59 * where status is: 60 * RAID Found, 61 * No RAID Found 62 * RAID not supported on this controller 63 * Invalid Controller 64 */ 65 66 typedef enum { 67 RAID_FOUND = 0x0, 68 RAID_NOT_FOUND, 69 RAID_NOT_SUPPORTED, 70 RAID_INVALID_CTRL, 71 RAID_DONT_USE 72 } raidctl_errno_t; 73 74 /* For no-mixup indexing of info_ctrl */ 75 #define INFO_CTRL 0 76 #define INFO_STATUS 1 77 78 static int **info_ctrl = NULL; 79 /* Length of conrollers list */ 80 static int ctrl_nums = 0; 81 82 83 #define DEVDIR "/dev/rdsk" 84 85 #define DO_HW_RAID_NOP -1 86 #define DO_HW_RAID_INFO 0 87 #define DO_HW_RAID_CREATE 1 88 #define DO_HW_RAID_DELETE 2 89 #define DO_HW_RAID_FLASH 3 90 91 /* values to use for raid level in raidctl */ 92 #define RAID_STRIPE 0 93 #define RAID_MIRROR 1 94 95 /* 96 * Error return codes 97 */ 98 #define SUCCESS 0 99 #define INVALID_ARG 1 100 #define FAILURE 2 101 102 /* 103 * FW Update Stuff 104 */ 105 106 /* signature and initial offset for PCI expansion rom images */ 107 #define PCIROM_SIG 0xaa55 /* offset 0h, length 2 bytes */ 108 #define PCIR_OFF 0x18 /* Pointer to PCI Data Structure */ 109 110 /* offsets in PCI data structure header */ 111 #define PCIR_DEVID 0x6 /* PCI device id */ 112 #define PCIR_CODETYPE 0x14 /* type of code (intel/fcode) */ 113 #define PCIR_INDICATOR 0x15 /* "last image" indicator */ 114 115 /* flags for image types */ 116 #define BIOS_IMAGE 0x1 117 #define FCODE_IMAGE 0x2 118 #define UNKNOWN_IMAGE 0x3 119 #define LAST_IMAGE 0x80 120 #define NOT_LAST_IMAGE 0 121 #define PCI_IMAGE_UNIT_SIZE 512 122 123 /* ID's and offsets for MPT Firmware images */ 124 #define FW_ROM_ID 0x5aea /* bytes 4 & 5 of file */ 125 #define FW_ROM_OFFSET_CHIP_TYPE 0x22 /* (U16) */ 126 #define FW_ROM_OFFSET_VERSION 0x24 /* (U16) */ 127 #define FW_ROM_OFFSET_VERSION_NAME 0x44 /* (32 U8) */ 128 129 /* ID's for supported chips */ 130 #define LSI_1030 0x30 131 #define LSI_1064 0x50 132 #define LSI_1068 0x54 133 #define LSI_1064E 0x56 134 #define LSI_1068E 0x58 135 136 /* Key to search for when looking for fcode version */ 137 #define FCODE_VERS_KEY1 0x12 138 #define FCODE_VERS_KEY2 0x7 139 #define BIOS_STR "LSI SCSI Host Adapter BIOS Driver: " 140 141 /* get a word from a buffer (works with non-word aligned offsets) */ 142 #define gw(x) (((x)[0]) + (((x)[1]) << 8)) 143 144 /* Number of disks currently supported, per RAID volume */ 145 #define N_DISKS 8 146 147 /* Maximum number of RAID volumes currently supported per HBA */ 148 #define N_RAIDVOLS 2 149 150 /* 151 * Function and strings to properly localize our prompt. 152 * So for example in german it would ask (ja/nein) or (yes/no) in 153 * english. 154 */ 155 static int yes(void); 156 static char yeschr[SCHAR_MAX + 2]; 157 static char nochr[SCHAR_MAX +2]; 158 159 typedef struct raidlist { 160 raid_config_t raid_config[N_RAIDVOLS]; 161 int controller; 162 char devctl[MAXPATHLEN]; 163 struct raidlist *next; 164 } raidlist_t; 165 166 static raidlist_t *raids; 167 168 /* 169 * usage: raidctl 170 * usage: raidctl [-f] -c primary secondary 171 * usage: raidctl [-f] -c -r 1 primary secondary 172 * usage: raidctl [-f] -c -r 0 disk1 disk2 [disk3] ... 173 * usage: raidctl [-f] -d volume 174 * usage: raidctl [-f] -F image_file controller 175 * usage: raidctl -l [controller...] 176 * example: 177 * raidctl -c c1t1d0 c1t2d0 178 * raidctl -c -r 0 c1t1d0 c1t2d0 c1t3d0 c1t4d0 179 * raidctl -d c1t1d0 180 * raidctl -F image 1 181 */ 182 static void 183 usage(char *prog_name) 184 { 185 (void) fprintf(stderr, gettext("usage: %s\n"), prog_name); 186 187 (void) fprintf(stderr, gettext("usage: %s [-f] -c primary secondary\n"), 188 prog_name); 189 190 (void) fprintf(stderr, gettext("usage: %s [-f] -c -r 1 primary " 191 "secondary\n"), prog_name); 192 193 (void) fprintf(stderr, gettext("usage: %s [-f] -c -r 0 disk1 disk2 " 194 "[disk3] ...\n"), prog_name); 195 196 (void) fprintf(stderr, gettext("usage: %s [-f] -d volume\n"), 197 prog_name); 198 199 (void) fprintf(stderr, 200 gettext("usage: %s [-f] -F image_file controller \n"), 201 prog_name); 202 203 (void) fprintf(stderr, gettext("usage: %s -l [controller...]\n"), 204 prog_name); 205 206 (void) fprintf(stderr, gettext("example:\n")); 207 (void) fprintf(stderr, "%s -c c1t1d0 c1t2d0\n", prog_name); 208 (void) fprintf(stderr, "%s -c -r 0 c1t1d0 c1t2d0 " 209 "c1t3d0 c1t4d0\n", prog_name); 210 (void) fprintf(stderr, "%s -d c1t1d0\n", prog_name); 211 (void) fprintf(stderr, "%s -F image 1\n", prog_name); 212 213 exit(1); 214 } 215 216 /* Make errno message more "user friendly" */ 217 static void 218 raidctl_error(char *str) 219 { 220 switch (errno) { 221 case EINVAL: 222 (void) fprintf(stderr, gettext("Error: " 223 "invalid argument would be returned\n")); 224 break; 225 case EIO: 226 case EFAULT: 227 (void) fprintf(stderr, 228 gettext("Error: Device inaccessible.\n")); 229 break; 230 case ENOTTY: 231 (void) fprintf(stderr, gettext("Error: " 232 "Device does not support requested action.\n")); 233 break; 234 default: 235 perror(str); 236 } 237 } 238 239 static int 240 get_link_path(const char *thing, char *buf) 241 { 242 if (readlink(thing, buf, MAXPATHLEN) < 0) 243 return (1); 244 return (0); 245 } 246 247 static int 248 get_ctrl_devctl(char *ctrl, char *b) 249 { 250 char devctl_buf[MAXPATHLEN]; 251 char *colon; 252 253 (void) strlcpy(devctl_buf, ctrl, MAXPATHLEN); 254 255 colon = strrchr(devctl_buf, ':'); 256 if (colon == NULL) 257 return (1); 258 259 *colon = 0; 260 (void) snprintf(devctl_buf, MAXPATHLEN, "%s:devctl", devctl_buf); 261 (void) strlcpy(b, devctl_buf, MAXPATHLEN); 262 return (0); 263 } 264 265 static int 266 get_devctl(char *disk, char *b) 267 { 268 char buf1[MAXPATHLEN] = {0}; 269 char devctl_buf[MAXPATHLEN]; 270 char *slash; 271 char devname[32]; 272 273 if (get_link_path(disk, buf1)) 274 return (1); 275 276 (void) strlcpy(devctl_buf, buf1, MAXPATHLEN); 277 278 slash = strrchr(devctl_buf, '/'); 279 if (slash == NULL) 280 return (1); 281 282 *slash = 0; 283 slash = strrchr(devctl_buf, '/'); 284 (void) strlcpy(devname, slash, 32); 285 *slash = 0; 286 287 (void) snprintf(devctl_buf, MAXPATHLEN, "%s%s:devctl", 288 devctl_buf, devname); 289 290 (void) strlcpy(b, devctl_buf, MAXPATHLEN); 291 292 return (0); 293 } 294 295 raidlist_t * 296 already_there(int controller) 297 { 298 raidlist_t *curr = raids; 299 300 while (curr != NULL) { 301 if (curr->controller == controller) 302 return (curr); 303 304 curr = curr->next; 305 } 306 307 return (NULL); 308 } 309 310 /* 311 * Display those controllers where RAID volumes were not found 312 */ 313 static void 314 print_no_raids() 315 { 316 int i, space = 0; 317 318 if (info_ctrl == NULL) 319 return; 320 321 for (i = 0; i < ctrl_nums; i++) { 322 /* Status of '0' means RAID exists at that controller */ 323 if (info_ctrl[i][INFO_STATUS] == RAID_FOUND || 324 info_ctrl[i][INFO_STATUS] == RAID_DONT_USE) 325 continue; 326 327 if (!space && raids != NULL) { 328 (void) printf("\n"); 329 space = 1; 330 } 331 332 /* switch statement used to enable gettext()'ing of text */ 333 switch (info_ctrl[i][INFO_STATUS]) { 334 case RAID_INVALID_CTRL: 335 (void) printf(gettext("Invalid controller '%d'\n"), 336 info_ctrl[i][INFO_CTRL]); 337 break; 338 case RAID_NOT_SUPPORTED: 339 (void) printf(gettext("No RAID supported " 340 "on controller '%d'\n"), 341 info_ctrl[i][INFO_CTRL]); 342 343 break; 344 default: 345 (void) printf(gettext("No RAID volumes found on " 346 "controller '%d'\n"), info_ctrl[i][INFO_CTRL]); 347 } 348 } 349 } 350 351 static void 352 add_raid_to_raidlist(char *ctrl_name, int controller) 353 { 354 raidlist_t *curr; 355 char buf[MAXPATHLEN] = {0}; 356 char buf1[MAXPATHLEN] = {0}; 357 int nvols; 358 int fd; 359 int i; 360 int n; 361 362 if (readlink(ctrl_name, buf, sizeof (buf)) < 0) 363 return; 364 365 if (get_ctrl_devctl(buf, buf1)) 366 return; 367 368 /* 369 * If "-l" was specified, then only look at those controllers 370 * listed as part of the command line input. 371 */ 372 if (info_ctrl != NULL) { 373 for (i = 0; i < ctrl_nums; i++) { 374 if (info_ctrl[i][INFO_STATUS] == RAID_DONT_USE) 375 continue; 376 if (controller == info_ctrl[i][INFO_CTRL]) 377 break; 378 } 379 /* return if we didn't find a controller */ 380 if (i == ctrl_nums) 381 return; 382 } 383 384 fd = open(buf1, O_RDONLY); 385 if (fd == -1) { 386 if (info_ctrl != NULL) 387 info_ctrl[i][INFO_STATUS] = RAID_INVALID_CTRL; 388 return; 389 } 390 391 /* 392 * query the HBA driver for volume capacity 393 */ 394 if (ioctl(fd, RAID_NUMVOLUMES, &nvols) < 0) { 395 if (info_ctrl != NULL) 396 info_ctrl[i][INFO_STATUS] = RAID_NOT_SUPPORTED; 397 (void) close(fd); 398 return; 399 } 400 401 /* 402 * now iterate through nvols configurations 403 */ 404 for (n = 0; n < nvols; n++) { 405 raid_config_t config; 406 407 /* use unitid to retrieve this volume */ 408 config.unitid = n; 409 if (ioctl(fd, RAID_GETCONFIG, &config) < 0) { 410 if (info_ctrl != NULL) 411 info_ctrl[i][INFO_STATUS] = RAID_NOT_SUPPORTED; 412 (void) close(fd); 413 return; 414 } 415 416 /* if ndisks is 0, this volume is not configured */ 417 if (config.ndisks == 0) 418 continue; 419 420 /* otherwise, we have a raid volume */ 421 if (info_ctrl != NULL) 422 info_ctrl[i][INFO_STATUS] = RAID_FOUND; 423 424 /* 425 * if raids has not been initialized, then do so. 426 * otherwise, see if this controller is in raids. 427 * if it is not, add it. then, add this volume to 428 * the raidlist 429 */ 430 if (raids == NULL) { 431 raids = (raidlist_t *)malloc(sizeof (raidlist_t)); 432 curr = raids; 433 } else { 434 if ((curr = already_there(controller)) != NULL) 435 goto already_there; 436 437 curr = raids; 438 439 /* add this controller to raids */ 440 while (curr->next != NULL) 441 curr = curr->next; 442 443 curr->next = (raidlist_t *)malloc(sizeof (raidlist_t)); 444 curr = curr->next; 445 } 446 447 already_there: 448 /* 449 * curr is now pointing to this controller. since we are 450 * adding controllers one at a time from do_search(), set 451 * curr->next to NULL so that we know where the end of our 452 * currently added controllers lies. 453 */ 454 curr->next = NULL; 455 curr->controller = controller; 456 (void) strlcpy(curr->devctl, buf1, sizeof (curr->devctl)); 457 (void) fflush(stdout); 458 (void) memcpy(&curr->raid_config[n], &config, 459 (sizeof (raid_config_t))); 460 } 461 462 if (info_ctrl != NULL && info_ctrl[i][INFO_STATUS] != RAID_FOUND) 463 info_ctrl[i][INFO_STATUS] = RAID_NOT_FOUND; 464 } 465 466 static void 467 print_header() 468 { 469 (void) printf(gettext("RAID\tVolume\tRAID\t\tRAID\t\tDisk")); 470 (void) printf("\n"); 471 (void) printf(gettext("Volume\tType\tStatus\t\tDisk\t\tStatus")); 472 (void) printf("\n"); 473 (void) printf("------------------------------------------------------"); 474 (void) printf("\n"); 475 } 476 477 static void 478 print_raidconfig(int c, raid_config_t config) 479 { 480 int i; 481 char voltype[8]; 482 483 /* print RAID volume target ID and volume type */ 484 if (config.raid_level == RAID_STRIPE) { 485 (void) snprintf(voltype, sizeof (voltype), "IS"); 486 } else if (config.raid_level == RAID_MIRROR) { 487 (void) snprintf(voltype, sizeof (voltype), "IM"); 488 } 489 490 (void) printf("c%dt%dd0\t%s\t", c, config.targetid, voltype); 491 492 /* Get RAID Info */ 493 if (config.flags & RAID_FLAG_RESYNCING && 494 config.state == RAID_STATE_DEGRADED) { 495 (void) printf(gettext("RESYNCING\t")); 496 } else if (config.state == RAID_STATE_DEGRADED) { 497 (void) printf(gettext("DEGRADED\t")); 498 } else if (config.state == RAID_STATE_OPTIMAL) { 499 (void) printf(gettext("OK\t\t")); 500 } else if (config.state == RAID_STATE_FAILED) { 501 (void) printf(gettext("FAILED\t\t")); 502 } else { 503 (void) printf(gettext("ERROR\t\t")); 504 } 505 506 /* Get RAID Disks */ 507 if (config.disk[0] != 0xff) 508 (void) printf("c%dt%dd0\t\t", c, config.disk[0]); 509 else 510 (void) printf("-\t\t"); 511 512 /* Get RAID Disk's Status */ 513 if (config.diskstatus[0] & RAID_DISKSTATUS_FAILED) { 514 (void) printf(gettext("FAILED\n")); 515 } else if (config.diskstatus[0] & RAID_DISKSTATUS_MISSING) { 516 (void) printf(gettext("MISSING\n")); 517 } else { 518 (void) printf(gettext("OK\n")); 519 } 520 521 for (i = 1; i < config.ndisks; i++) { 522 if (config.disk[i] != 0xff) 523 (void) printf("\t\t\t\tc%dt%dd0\t\t", c, 524 config.disk[i]); 525 else 526 (void) printf("\t\t\t\t-\t\t"); 527 528 if (config.diskstatus[i] & RAID_DISKSTATUS_FAILED) { 529 (void) printf(gettext("FAILED\n")); 530 } else if (config.diskstatus[i] & RAID_DISKSTATUS_MISSING) { 531 (void) printf(gettext("MISSING\n")); 532 } else { 533 (void) printf(gettext("OK\n")); 534 } 535 } 536 } 537 538 static void 539 print_disklist() 540 { 541 raidlist_t *curr = raids; 542 int i; 543 544 while (curr != NULL) { 545 for (i = 0; i < N_RAIDVOLS; i++) { 546 if (curr->raid_config[i].ndisks != 0) { 547 print_raidconfig(curr->controller, 548 curr->raid_config[i]); 549 } 550 } 551 curr = curr->next; 552 } 553 } 554 555 static void 556 free_disklist() 557 { 558 raidlist_t *curr = raids; 559 560 while (curr != NULL) { 561 raidlist_t *temp; 562 temp = curr; 563 curr = curr->next; 564 free(temp); 565 } 566 } 567 568 static void 569 do_search() 570 { 571 DIR *dir; 572 struct dirent *dp; 573 char buf[MAXPATHLEN]; 574 int c; 575 int i, j; 576 577 /* 578 * In case repeated numbers were found, assign the repititions as 579 * RAID_DONT_USE 580 */ 581 for (i = 0; i < ctrl_nums; i++) { 582 int first_one = 1; 583 for (j = 0; j < ctrl_nums; j++) { 584 if (info_ctrl[i][INFO_CTRL] == 585 info_ctrl[j][INFO_CTRL]) { 586 if (info_ctrl[j][INFO_STATUS] == RAID_DONT_USE) 587 continue; 588 if (first_one) { 589 first_one = 0; 590 } else { 591 info_ctrl[j][INFO_STATUS] = 592 RAID_DONT_USE; 593 } 594 } 595 } 596 } 597 598 if ((dir = opendir("/dev/cfg")) == NULL) { 599 (void) fprintf(stderr, 600 gettext("Cannot open /dev/cfg: %s\n"), strerror(errno)); 601 return; 602 } 603 /* 604 * iterate over the controllers and add any 605 * controllers with RAID volumes to the raids 606 * list, one at a time 607 */ 608 while ((dp = readdir(dir)) != NULL) { 609 if (strcmp(dp->d_name, ".") == 0 || 610 strcmp(dp->d_name, "..") == 0) 611 continue; 612 if (sscanf(dp->d_name, "c%d", &c) != 1) 613 continue; 614 (void) snprintf(buf, sizeof (buf), "/dev/cfg/%s", dp->d_name); 615 add_raid_to_raidlist(buf, c); 616 } 617 (void) closedir(dir); 618 } 619 620 /* 621 * do_info() will do the following: 622 * - create a list of disks' devctls 623 * - try to talk to each of the devctls found 624 * - if raid configuration is found, display it. 625 */ 626 static void 627 do_info() 628 { 629 int i; 630 (void) chdir(DEVDIR); 631 632 do_search(); 633 634 if (raids == NULL) { 635 if (info_ctrl != NULL) { 636 print_no_raids(); 637 for (i = 0; i < ctrl_nums; i++) 638 free(info_ctrl[i]); 639 free(info_ctrl); 640 } else { 641 (void) printf(gettext("No RAID volumes found\n")); 642 } 643 return; 644 } 645 646 print_header(); 647 print_disklist(); 648 print_no_raids(); 649 free_disklist(); 650 if (info_ctrl) { 651 for (i = 0; i < ctrl_nums; i++) 652 free(info_ctrl[i]); 653 free(info_ctrl); 654 } 655 } 656 657 static int 658 disk_in_raid(int c, int t) 659 { 660 raidlist_t *curr; 661 raid_config_t raid; 662 int i, j, n; 663 664 do_search(); 665 curr = raids; 666 667 while (curr != NULL) { 668 if (curr->controller == c) { 669 for (i = 0; i < N_RAIDVOLS; i++) { 670 raid = curr->raid_config[i]; 671 if ((n = raid.ndisks) != 0) { 672 for (j = 0; j < n; j++) { 673 if (raid.disk[j] == t) { 674 return (1); 675 } 676 } 677 } 678 } 679 } 680 curr = curr->next; 681 } 682 return (0); 683 } 684 685 static int 686 disk_there(int c, int t) 687 { 688 char disk[100]; 689 int fd; 690 691 (void) snprintf(disk, sizeof (disk), "c%dt%dd0s2", c, t); 692 693 fd = open(disk, O_RDWR | O_NDELAY); 694 if (fd == -1) { 695 return (-1); 696 } 697 698 (void) close(fd); 699 return (0); 700 } 701 702 static int 703 get_controller(char *dev) 704 { 705 raidlist_t *curr; 706 int c; 707 do_search(); 708 curr = raids; 709 while (curr != NULL) { 710 if (strcmp(curr->devctl, dev) == 0) { 711 c = curr->controller; 712 break; 713 } 714 curr = curr->next; 715 } 716 717 free_disklist(); 718 return (c); 719 } 720 721 static int 722 disk_mounted(char *d) 723 { 724 struct mnttab mt; 725 FILE *f = fopen("/etc/mnttab", "r"); 726 727 while (getmntent(f, &mt) != EOF) 728 if (strstr(mt.mnt_special, d) != NULL) 729 return (1); 730 731 return (0); 732 } 733 734 static int 735 disk_big_enough(char **d, diskaddr_t *cap, int *errcond) 736 { 737 struct dk_minfo minfo; 738 char disk[N_DISKS][MAXPATHLEN]; 739 uint_t disk_lbsize[N_DISKS]; 740 diskaddr_t disk_capacity[N_DISKS]; 741 int i, fd; 742 743 for (i = 0; i < N_DISKS; i++) { 744 if (d[i] == NULL) 745 break; 746 747 (void) snprintf(disk[i], sizeof (disk[i]), DEVDIR"/%ss2", d[i]); 748 fd = open(disk[i], O_RDWR | O_NDELAY); 749 if (fd == -1) 750 return (FAILURE); 751 if (ioctl(fd, DKIOCGMEDIAINFO, &minfo) == -1) { 752 (void) close(fd); 753 return (FAILURE); 754 } 755 756 disk_lbsize[i] = minfo.dki_lbsize; 757 disk_capacity[i] = minfo.dki_capacity; 758 759 /* lbsize must be the same on all disks */ 760 if (disk_lbsize[0] != disk_lbsize[i]) { 761 *errcond = 2; 762 return (INVALID_ARG); 763 } 764 765 /* ensure drive capacity is greater than or equal to first */ 766 if (disk_capacity[0] > disk_capacity[i]) { 767 *errcond = 1; 768 return (INVALID_ARG); 769 } 770 (void) close(fd); 771 } 772 773 /* 774 * setting capacity as the dk_minfo.dki_capacity of d[0] 775 * this is the number of dki_lbsize blocks on disk 776 */ 777 *cap = disk_capacity[0]; 778 return (SUCCESS); 779 } 780 781 static int 782 do_config_change_state(cfga_cmd_t cmd, int d, int c) 783 { 784 cfga_err_t cfga_err; 785 char *ap_id; 786 int rv = SUCCESS; 787 int count = 0; 788 789 ap_id = (char *)malloc(100); 790 if (ap_id == NULL) 791 return (FAILURE); 792 793 (void) snprintf(ap_id, 100, "c%d::dsk/c%dt%dd0", c, c, d); 794 795 /* 796 * If the config_change_state() funcation fails, we want to 797 * retry. If the retry fails, then we return failure to fail. 798 * 799 * If we fail: 800 * 801 * If we were called from create, then we fail the raid 802 * creation. 803 * 804 * If we were called from delete, then the disk will not 805 * be re-configured by raidctl. 806 */ 807 do { 808 cfga_err = config_change_state(cmd, 1, &ap_id, NULL, 809 NULL, NULL, NULL, 0); 810 count++; 811 } while (cfga_err != CFGA_OK && count < 2); 812 813 if (cfga_err != CFGA_OK) 814 rv = FAILURE; 815 816 free(ap_id); 817 return (rv); 818 } 819 820 static int 821 do_create(char **d, int rlevel, int force) 822 { 823 raid_config_t config; 824 raid_config_t newvol; 825 char disk[N_DISKS][MAXPATHLEN] = {0}; 826 int map[N_DISKS]; 827 char channel1[MAXPATHLEN]; 828 char channel2[MAXPATHLEN]; 829 diskaddr_t capacity; 830 int fd, fd2, size, errcond; 831 int c[N_DISKS]; 832 int t[N_DISKS]; 833 char *tmp; 834 int loc, i, devid, n, ndisks = 0; 835 836 (void) chdir(DEVDIR); 837 838 /* initialize target map */ 839 for (i = 0; i < N_DISKS; i++) 840 map[i] = -1; 841 842 for (i = 0; i < N_DISKS; i++) { 843 if (d[i] == NULL) 844 break; 845 846 if ((sscanf(d[i], "c%dt%dd0", &c[i], &t[i])) != 2 || 847 t[i] < 0) { 848 (void) fprintf(stderr, 849 gettext("Invalid disk format.\n")); 850 return (INVALID_ARG); 851 } 852 853 /* ensure that all disks are on the same controller, */ 854 if (c[i] != c[0]) { 855 (void) fprintf(stderr, gettext("Disks must be " 856 "on the same controller.\n")); 857 return (INVALID_ARG); 858 } 859 860 /* that all disks are online, */ 861 if (disk_there(c[0], t[i])) { 862 (void) printf(gettext("Disk 'c%dt%dd0' is not " 863 "present.\n"), c[0], t[i]); 864 (void) printf(gettext("Cannot create RAID volume.\n")); 865 return (INVALID_ARG); 866 } 867 868 /* that there are no duplicate disks, */ 869 loc = t[i]; 870 if (map[loc] == -1) { 871 map[loc] = t[i]; 872 } else { 873 (void) fprintf(stderr, 874 gettext("Disks must be different.\n")); 875 return (INVALID_ARG); 876 } 877 878 /* that no disk is already in use by another volume, */ 879 if (disk_in_raid(c[0], t[i])) { 880 (void) fprintf(stderr, gettext("Disk %s is already in " 881 "a RAID volume.\n"), d[i]); 882 return (INVALID_ARG); 883 } 884 885 /* that no target's id is lower than the raidtarg, */ 886 if (t[0] > t[i]) { 887 (void) fprintf(stderr, gettext("First target ID must " 888 "be less than other member target IDs.\n")); 889 return (INVALID_ARG); 890 } 891 892 (void) snprintf(disk[i], sizeof (disk[i]), DEVDIR"/%ss2", d[i]); 893 ndisks++; 894 } 895 896 /* confirm minimum number of disks */ 897 if (ndisks < 2) { 898 (void) fprintf(stderr, gettext("At least two disks are required" 899 " for RAID creation.\n")); 900 return (INVALID_ARG); 901 } 902 903 /* validate the drive capacities */ 904 switch (disk_big_enough(d, &capacity, &errcond)) { 905 case FAILURE: 906 return (FAILURE); 907 case INVALID_ARG: 908 switch (errcond) { 909 case 1: 910 (void) fprintf(stderr, gettext("Cannot create RAID volume when " 911 "primary disk is larger than secondary disk.\n")); 912 break; 913 case 2: 914 (void) fprintf(stderr, gettext("Cannot create RAID volume when " 915 "disk block sizes differ.\n")); 916 } 917 return (INVALID_ARG); 918 } 919 920 /* 921 * capacity is now set to the number of blocks on a disk, which is 922 * the total capacity of a mirror. the capacity of a stripe is the 923 * cumulative amount of blocks on all disks 924 */ 925 if (rlevel == RAID_STRIPE) 926 capacity *= ndisks; 927 928 if (get_devctl(disk[0], channel1)) 929 return (FAILURE); 930 931 fd = open(channel1, O_RDONLY); 932 if (fd == -1) { 933 perror(channel1); 934 return (FAILURE); 935 } 936 937 /* 938 * query the HBA driver for volume capacity 939 */ 940 if (ioctl(fd, RAID_NUMVOLUMES, &n) < 0) { 941 raidctl_error("RAID_NUMVOLUMES"); 942 goto fail; 943 } 944 945 /* 946 * current support for both LSI1030 and LSI1064/1068 HBAs 947 */ 948 if (ioctl(fd, RAID_GETDEVID, &devid) < 0) { 949 raidctl_error("RAID_GETDEVID"); 950 goto fail; 951 } 952 953 if ((devid == LSI_1064) || (devid == LSI_1064E) || 954 (devid == LSI_1068) || (devid == LSI_1068E)) { 955 /* 956 * no secondary channel, just check to make 957 * sure we can fit a new volume 958 */ 959 for (i = 0; i < n; i++) { 960 config.unitid = i; 961 if (ioctl(fd, RAID_GETCONFIG, &config) < 0) { 962 raidctl_error("RAID_GETCONFIG"); 963 goto fail; 964 } 965 966 if (config.ndisks == 0) 967 break; 968 } 969 970 if (i == n) { 971 (void) printf(gettext("HBA supports a maximum of %d " 972 "RAID Volumes, HBA is full\n"), n); 973 goto fail; 974 } 975 976 /* 977 * we have the capacity to add a volume, now confirm the 978 * creation. the 1064/1068 uses a much larger metadata region 979 * than the 1030 (64MB, as opposed to 16KB). this larger 980 * reservation is enough to alter the disk label. therefore, 981 * once the volume is created, it must be relabeled. 982 * first, confirm that no file systems are mounted, as 983 * we will be pulling the disk out from under them 984 */ 985 for (i = 0; i < ndisks; i++) { 986 if (disk_mounted(d[i])) { 987 (void) fprintf(stderr, gettext("Cannot create " 988 "RAID volume, disk \"%s\" is mounted " 989 ".\n"), d[i]); 990 return (INVALID_ARG); 991 } 992 } 993 994 /* 995 * will not support data migration or disk relabeling with 996 * this utility, and so next we must confirm the creation as 997 * all data on member disks will be lost. 998 */ 999 if (!force) { 1000 (void) fprintf(stderr, gettext("Creating RAID volume " 1001 "c%dt%dd0 will destroy all data on member disks, " 1002 "proceed (%s/%s)? "), c[0], t[0], yeschr, nochr); 1003 if (!yes()) { 1004 (void) fprintf(stderr, gettext("RAID volume " 1005 "c%dt%dd0 not created.\n\n"), c[0], t[0]); 1006 (void) close(fd); 1007 return (SUCCESS); 1008 } 1009 } 1010 1011 /* 1012 * we are ready to move onto the creation 1013 */ 1014 goto no_secondary_channel; 1015 } 1016 1017 /* 1018 * LSI1030, support for single IM volume 1019 */ 1020 if (rlevel != RAID_MIRROR) { 1021 (void) printf(gettext("HBA only supports RAID " 1022 "level 1 (mirrored) volumes\n")); 1023 goto fail; 1024 } 1025 /* 1026 * look up the volume configuration 1027 */ 1028 config.unitid = n; 1029 if (ioctl(fd, RAID_GETCONFIG, &config) < 0) { 1030 raidctl_error("RAID_GETCONFIG"); 1031 goto fail; 1032 } 1033 1034 if (config.ndisks != 0) { 1035 (void) printf(gettext("RAID Volume already exists " 1036 "on this controller 'c%dt%dd0'\n"), 1037 c[0], config.targetid); 1038 goto fail; 1039 } 1040 1041 /* 1042 * Make sure there isn't a raid created on this controller's 1043 * other channel, if it has multiple channels 1044 */ 1045 (void) strlcpy(channel2, channel1, sizeof (channel2)); 1046 tmp = strrchr(channel2, ':'); 1047 tmp[0] = 0; 1048 size = strlen(channel2); 1049 1050 /* 1051 * Make sure that the secondary disk is not mounted 1052 */ 1053 if (disk_mounted(disk[1])) { 1054 (void) fprintf(stderr, gettext("Cannot create RAID volume when " 1055 "secondary disk \"%s\" is mounted.\n"), disk[1]); 1056 return (INVALID_ARG); 1057 } 1058 1059 /* 1060 * Format the channel string for the other channel so we can 1061 * see if a raid exists on it. In this case if we are being 1062 * asked to create a raid on channel 2 (indicated by the 1,1 1063 * at the end of the string) we want to check channel 1), 1064 * otherwise we will check channel 2. 1065 */ 1066 if (channel2[size - 2] == ',') { 1067 channel2[size - 1] = 0; 1068 channel2[size - 2] = 0; 1069 (void) snprintf(channel2, sizeof (channel2), 1070 "%s:devctl", channel2); 1071 } else { 1072 (void) snprintf(channel2, sizeof (channel2), 1073 "%s,1:devctl", channel2); 1074 } 1075 1076 fd2 = open(channel2, O_RDONLY); 1077 if (fd2 == -1) { 1078 if (errno == ENOENT) 1079 goto no_secondary_channel; 1080 perror(channel2); 1081 goto fail; 1082 } 1083 1084 if (ioctl(fd2, RAID_GETCONFIG, &config) < 0) { 1085 goto fail; 1086 } 1087 1088 if (config.ndisks != 0) { 1089 int cx; 1090 cx = get_controller(channel2); 1091 (void) printf(gettext("RAID Volume already exists " 1092 "on this controller 'c%dt%dd0'\n"), cx, 1093 config.targetid); 1094 goto fail; 1095 } 1096 1097 no_secondary_channel: 1098 1099 /* all checks complete, fill in the config */ 1100 newvol.targetid = t[0]; 1101 newvol.disk[0] = t[0]; 1102 newvol.raid_level = rlevel; 1103 newvol.ndisks = ndisks; 1104 newvol.raid_capacity = capacity; 1105 1106 /* populate config.disk, and unconfigure all disks, except targetid */ 1107 for (i = 1; i < ndisks; i++) { 1108 if (do_config_change_state(CFGA_CMD_UNCONFIGURE, 1109 t[i], c[0])) { 1110 perror("config_change_state"); 1111 goto fail; 1112 } 1113 newvol.disk[i] = t[i]; 1114 } 1115 1116 if (ioctl(fd, RAID_CREATE, &newvol)) { 1117 /* reconfigure all disks, except targetid */ 1118 for (i = 1; i < ndisks; i++) { 1119 (void) do_config_change_state(CFGA_CMD_CONFIGURE, 1120 newvol.disk[i], c[0]); 1121 } 1122 raidctl_error("RAID_CREATE"); 1123 goto fail; 1124 } 1125 1126 (void) printf(gettext("Volume 'c%dt%dd0' created\n"), c[0], t[0]); 1127 (void) close(fd); 1128 (void) close(fd2); 1129 return (SUCCESS); 1130 1131 fail: 1132 (void) close(fd); 1133 (void) close(fd2); 1134 return (FAILURE); 1135 } 1136 1137 static int 1138 do_delete(char *d, int force) 1139 { 1140 raid_config_t config; 1141 char disk1[MAXPATHLEN]; 1142 char buf[MAXPATHLEN]; 1143 int fd; 1144 int target; 1145 int ctrl; 1146 int i, j; 1147 int wrong_targ = 0; 1148 int nvols; 1149 uint8_t t; 1150 1151 (void) chdir(DEVDIR); 1152 1153 if ((sscanf(d, "c%dt%dd0", &ctrl, &target)) != 2) { 1154 (void) fprintf(stderr, gettext("Invalid disk format.\n")); 1155 return (INVALID_ARG); 1156 } 1157 t = (uint8_t)target; 1158 1159 (void) snprintf(disk1, sizeof (disk1), DEVDIR"/%ss2", d); 1160 1161 if (get_devctl(disk1, buf) != 0) { 1162 (void) fprintf(stderr, gettext("Not a volume '%s'\n"), d); 1163 return (FAILURE); 1164 } 1165 1166 fd = open(buf, O_RDONLY); 1167 if (fd == -1) { 1168 perror(buf); 1169 return (FAILURE); 1170 } 1171 1172 if (ioctl(fd, RAID_NUMVOLUMES, &nvols)) { 1173 raidctl_error("RAID_NUMVOLUMES"); 1174 goto fail; 1175 } 1176 1177 for (i = 0; i < nvols; i++) { 1178 config.unitid = i; 1179 if (ioctl(fd, RAID_GETCONFIG, &config)) { 1180 raidctl_error("RAID_GETCONFIG"); 1181 goto fail; 1182 } 1183 if (config.ndisks != 0) { 1184 /* there is a RAID volume in this slot */ 1185 if (config.targetid != t) { 1186 wrong_targ++; 1187 continue; 1188 } 1189 /* and it's our target */ 1190 break; 1191 } 1192 } 1193 1194 if (i == nvols) { 1195 /* we found no RAID volumes */ 1196 (void) fprintf(stderr, gettext("No RAID volumes exist on " 1197 "controller '%d'\n"), ctrl); 1198 goto fail; 1199 } 1200 1201 if (wrong_targ == nvols) { 1202 /* we found RAID volumes, but none matched */ 1203 (void) fprintf(stderr, 1204 gettext("RAID volume 'c%dt%dd0' does not exist\n"), 1205 ctrl, t); 1206 goto fail; 1207 } 1208 1209 /* if this volume is a stripe, all data will be lost */ 1210 if (config.raid_level == RAID_STRIPE) { 1211 if (disk_mounted(d)) { 1212 (void) fprintf(stderr, gettext("Cannot delete " 1213 "RAID0 volume, \"%s\" is mounted.\n"), d); 1214 return (INVALID_ARG); 1215 } 1216 if (!force) { 1217 (void) fprintf(stderr, gettext("Deleting volume " 1218 "c%dt%dd0 will destroy all data it contains, " 1219 "proceed (%s/%s)? "), ctrl, t, yeschr, nochr); 1220 if (!yes()) { 1221 (void) fprintf(stderr, gettext("RAID volume " 1222 "c%dt%dd0 not deleted.\n\n"), ctrl, t); 1223 (void) close(fd); 1224 return (SUCCESS); 1225 } 1226 } 1227 } 1228 /* if this volume is a mirror, prompt user to verify the operation */ 1229 else if (config.raid_level == RAID_MIRROR && !force) { 1230 (void) fprintf(stderr, gettext("Are you sure you want to " 1231 "delete RAID-1 Volume c%dt%dd0(%s/%s)? "), 1232 ctrl, t, yeschr, nochr); 1233 if (!yes()) { 1234 (void) fprintf(stderr, gettext("RAID volume " 1235 "c%dt%dd0 not deleted.\n\n"), ctrl, t); 1236 (void) close(fd); 1237 return (SUCCESS); 1238 } 1239 } 1240 1241 if (ioctl(fd, RAID_DELETE, &t)) { 1242 perror("RAID_DELETE"); 1243 goto fail; 1244 } 1245 1246 /* reconfigure all disks, except targetid */ 1247 for (j = 1; j < config.ndisks; j++) { 1248 (void) do_config_change_state(CFGA_CMD_CONFIGURE, 1249 config.disk[j], ctrl); 1250 } 1251 1252 (void) fprintf(stderr, gettext("Volume 'c%dt%dd0' deleted.\n"), 1253 ctrl, target); 1254 (void) close(fd); 1255 return (SUCCESS); 1256 1257 fail: 1258 (void) close(fd); 1259 return (FAILURE); 1260 } 1261 1262 static void 1263 getimagetype(uint8_t *rombuf, int *imagetype) 1264 { 1265 uint8_t type = rombuf[gw(&rombuf[PCIR_OFF]) + PCIR_CODETYPE]; 1266 if (type == 0) { 1267 *imagetype = BIOS_IMAGE; 1268 return; 1269 } 1270 if (type == 1) { 1271 *imagetype = FCODE_IMAGE; 1272 return; 1273 } 1274 } 1275 1276 static int 1277 getfcodever(uint8_t *rombuf, uint32_t nbytes, char **fcodeversion) 1278 { 1279 int x, y, size; 1280 int found_1 = 0, found_2 = 0; 1281 int image_length = 0; 1282 int no_of_images = 0; 1283 uint8_t *rombuf_1 = NULL; 1284 uint16_t image_units = 0; 1285 1286 /* 1287 * Single Image - Open firmware image 1288 */ 1289 if (rombuf[gw(&rombuf[PCIR_OFF]) + PCIR_CODETYPE] == 1) { 1290 rombuf_1 = rombuf + gw(rombuf + PCIR_OFF) + PCI_PDS_INDICATOR; 1291 no_of_images = 1; 1292 goto process_image; 1293 } 1294 1295 /* 1296 * Combined Image - First Image - x86/PC-AT Bios image 1297 */ 1298 if (rombuf[gw(&rombuf[PCIR_OFF]) + PCIR_CODETYPE] != 0) { 1299 (void) fprintf(stderr, gettext("This is neither open image" 1300 " nor Bios/Fcode combined image\n")); 1301 return (1); 1302 } 1303 1304 /* 1305 * Seek to 2nd Image 1306 */ 1307 rombuf_1 = rombuf + gw(rombuf + PCI_ROM_PCI_DATA_STRUCT_PTR); 1308 image_units = gw(rombuf_1 + PCI_PDS_IMAGE_LENGTH); 1309 image_length = image_units * PCI_IMAGE_UNIT_SIZE; 1310 rombuf_1 += image_length; 1311 1312 /* 1313 * Combined Image - Second Image - Open Firmware image 1314 */ 1315 if (rombuf_1[PCI_PDS_CODE_TYPE] != 1) { 1316 (void) fprintf(stderr, gettext("This is neither open image" 1317 " nor Bios/Fcode combined image\n")); 1318 return (1); 1319 } 1320 rombuf_1 += PCI_PDS_INDICATOR; 1321 no_of_images = 2; 1322 1323 process_image: 1324 /* 1325 * This should be the last image 1326 */ 1327 if (*rombuf_1 != LAST_IMAGE) { 1328 (void) fprintf(stderr, gettext("This is not a valid " 1329 "Bios/Fcode image file\n")); 1330 return (1); 1331 } 1332 1333 /* 1334 * Scan through the bios/fcode file to get the fcode version 1335 * 0x12 and 0x7 indicate the start of the fcode version string 1336 */ 1337 for (x = 0; x < (nbytes - 8); x++) { 1338 if ((rombuf[x] == FCODE_VERS_KEY1) && 1339 (rombuf[x+1] == FCODE_VERS_KEY2) && 1340 (rombuf[x+2] == 'v') && (rombuf[x+3] == 'e') && 1341 (rombuf[x+4] == 'r') && (rombuf[x+5] == 's') && 1342 (rombuf[x+6] == 'i') && (rombuf[x+7] == 'o') && 1343 (rombuf[x+8] == 'n')) { 1344 found_1 = 1; 1345 break; 1346 } 1347 } 1348 1349 /* 1350 * Store the version string if we have found the beginning of it 1351 */ 1352 if (found_1) { 1353 while (x > 0) { 1354 if (rombuf[--x] == FCODE_VERS_KEY1) { 1355 if (rombuf[x-1] != FCODE_VERS_KEY1) { 1356 x++; 1357 } 1358 break; 1359 } 1360 } 1361 if (x > 0) { 1362 *fcodeversion = (char *)malloc(rombuf[x] + 1); 1363 for (y = 0; y < rombuf[x]; y++) { 1364 (*fcodeversion)[y] = rombuf[x+y+1]; 1365 } 1366 (*fcodeversion)[y] = '\0'; 1367 } else { 1368 found_1 = 0; 1369 } 1370 } 1371 1372 /* 1373 * Scan through the bios/fcode file to get the Bios version 1374 * "@(#)" string indicates the start of the Bios version string 1375 * Append this version string, after already existing fcode version. 1376 */ 1377 if (no_of_images == 2) { 1378 for (x = 0; x < (nbytes - 4); x++) { 1379 if ((rombuf[x] == '@') && (rombuf[x+1] == '(') && 1380 (rombuf[x+2] == '#') && (rombuf[x+3] == ')')) { 1381 found_2 = 1; 1382 break; 1383 } 1384 } 1385 1386 if (found_2) { 1387 x += 4; 1388 (*fcodeversion)[y] = '\n'; 1389 size = y + strlen((char *)(rombuf + x)) + 1390 strlen(BIOS_STR) + 2; 1391 *fcodeversion = (char *)realloc((*fcodeversion), size); 1392 y++; 1393 (*fcodeversion)[y] = '\0'; 1394 (void) strlcat(*fcodeversion, BIOS_STR, size); 1395 (void) strlcat(*fcodeversion, (char *)(rombuf + x), 1396 size); 1397 } 1398 } 1399 1400 return ((found_1 || found_2) ? 0 : 1); 1401 } 1402 1403 static void 1404 getfwver(uint8_t *rombuf, char *fwversion) 1405 { 1406 (void) snprintf(fwversion, 8, "%d.%.2d.%.2d.%.2d", 1407 rombuf[FW_ROM_OFFSET_VERSION + 3], 1408 rombuf[FW_ROM_OFFSET_VERSION + 2], 1409 rombuf[FW_ROM_OFFSET_VERSION + 1], 1410 rombuf[FW_ROM_OFFSET_VERSION + 0]); 1411 } 1412 1413 static int 1414 getbioscodever(uint8_t *rombuf, uint32_t nbytes, char **biosversion) 1415 { 1416 int x, size; 1417 int found = 0; 1418 1419 for (x = 0; x < (nbytes - 4); x++) { 1420 if ((rombuf[x] == '@') && (rombuf[x+1] == '(') && 1421 (rombuf[x+2] == '#') && (rombuf[x+3] == ')')) { 1422 found = 1; 1423 break; 1424 } 1425 } 1426 1427 if (found) { 1428 x += 4; 1429 size = strlen((char *)(rombuf + x)) + strlen(BIOS_STR) + 1; 1430 *biosversion = (char *)realloc((*biosversion), size); 1431 bcopy((char *)(rombuf + x), *biosversion, size - 1); 1432 (*biosversion)[size - 1] = '\0'; 1433 } 1434 1435 return (found); 1436 1437 } 1438 1439 static int 1440 checkfile(uint8_t *rombuf, uint32_t nbytes, uint32_t chksum, int *imagetype) 1441 { 1442 char *imageversion = NULL; 1443 char *biosversion = NULL; 1444 char *fwversion; 1445 1446 fwversion = (char *)malloc(8); 1447 1448 if (gw(&rombuf[0]) == PCIROM_SIG) { 1449 1450 *imagetype = UNKNOWN_IMAGE; 1451 getimagetype(rombuf, imagetype); 1452 1453 if (*imagetype == FCODE_IMAGE) { 1454 if (getfcodever(rombuf, nbytes, &imageversion) == 0 && 1455 imageversion != NULL) { 1456 (void) printf(gettext("Image file contains " 1457 "fcode version \t%s\n"), imageversion); 1458 free(imageversion); 1459 } 1460 } else if (*imagetype == BIOS_IMAGE) { 1461 if (getbioscodever(rombuf, nbytes, &biosversion) == 1 && 1462 biosversion != NULL) { 1463 (void) printf(gettext("Image file contains " 1464 "BIOS version \t%s\n"), biosversion); 1465 free(biosversion); 1466 } 1467 } else { 1468 /* When imagetype equals to UNKNOWN_IMAGE */ 1469 return (-1); 1470 } 1471 1472 } else if (gw(&rombuf[3]) == FW_ROM_ID) { 1473 if (chksum != 0) { 1474 (void) fprintf(stderr, 1475 gettext("The ROM checksum appears bad " 1476 "(%d)\n"), chksum); 1477 return (-1); 1478 } 1479 getfwver(rombuf, fwversion); 1480 1481 if ((gw(&rombuf[FW_ROM_OFFSET_CHIP_TYPE]) & 1482 MPI_FW_HEADER_PID_PROD_MASK) == 1483 MPI_FW_HEADER_PID_PROD_IM_SCSI) { 1484 (void) printf(gettext("ROM image contains " 1485 "MPT firmware version %s " 1486 "(w/Integrated Mirroring)\n"), 1487 fwversion); 1488 } else { 1489 (void) printf(gettext("ROM image contains " 1490 "MPT firmware ""version %s\n"), 1491 fwversion); 1492 } 1493 free(fwversion); 1494 } else { 1495 1496 #ifdef DEBUG 1497 (void) fprintf(stderr, "Not valid FCODE image %x\n", gw(&rombuf[0])); 1498 #else 1499 (void) fprintf(stderr, gettext("Not valid FCODE image\n")); 1500 #endif 1501 return (-1); 1502 } 1503 return (0); 1504 } 1505 1506 static int 1507 updateflash(uint8_t *rombuf, uint32_t nbytes, char *devctl) 1508 { 1509 int fd = 0; 1510 update_flash_t flashdata; 1511 1512 fd = open(devctl, O_RDONLY); 1513 if (fd == -1) { 1514 perror(devctl); 1515 return (-1); 1516 } 1517 (void) memset(&flashdata, 0, sizeof (flashdata)); 1518 flashdata.ptrbuffer = (caddr_t)rombuf; 1519 flashdata.size = nbytes; 1520 if ((rombuf[0] == 0x55) && (rombuf[1] == 0xaa)) { 1521 flashdata.type = FW_TYPE_FCODE; 1522 } else { 1523 flashdata.type = FW_TYPE_UCODE; 1524 } 1525 1526 if (ioctl(fd, RAID_UPDATEFW, &flashdata)) { 1527 raidctl_error("RAID_UPDATEFW"); 1528 (void) close(fd); 1529 return (-1); 1530 } 1531 1532 (void) close(fd); 1533 return (0); 1534 } 1535 1536 static int 1537 readfile(char *filespec, uint8_t **rombuf, uint32_t *nbytes, uint32_t *chksum) 1538 { 1539 struct stat statbuf; 1540 uint32_t count; 1541 uint32_t checksum = 0; 1542 int fd, i; 1543 uint8_t *filebuf; 1544 1545 1546 if ((fd = open((const char *)filespec, O_RDONLY | O_NDELAY)) == -1) { 1547 perror(filespec); 1548 return (-1); 1549 } 1550 1551 if (fstat(fd, &statbuf) != 0) { 1552 perror("fstat"); 1553 (void) fprintf(stderr, 1554 gettext("Error getting stats on file\n")); 1555 (void) close(fd); 1556 return (-1); 1557 } 1558 1559 #ifdef DEBUG 1560 (void) printf("Filesize = %ld\n", statbuf.st_size); 1561 #endif 1562 1563 filebuf = (uint8_t *)realloc(*rombuf, statbuf.st_size + *nbytes); 1564 1565 count = read(fd, filebuf + *nbytes, statbuf.st_size); 1566 (void) close(fd); 1567 if (count != statbuf.st_size) { 1568 perror("size check"); 1569 (void) fprintf(stderr, gettext("File is corrupt\n")); 1570 return (-1); 1571 } 1572 1573 for (i = 0; i < *nbytes; i++) 1574 checksum += filebuf[i] << (8 * (i & 3)); 1575 1576 *rombuf = filebuf; 1577 *nbytes = *nbytes + count; 1578 *chksum = checksum; 1579 1580 return (0); 1581 } 1582 1583 static int 1584 yes(void) 1585 { 1586 int i, b; 1587 char ans[SCHAR_MAX + 1]; 1588 1589 for (i = 0; ; i++) { 1590 b = getchar(); 1591 if (b == '\n' || b == '\0' || b == EOF) { 1592 ans[i] = 0; 1593 break; 1594 } 1595 if (i < SCHAR_MAX) 1596 ans[i] = b; 1597 } 1598 if (i >= SCHAR_MAX) { 1599 i = SCHAR_MAX; 1600 ans[SCHAR_MAX] = 0; 1601 } 1602 if ((i != 0) && ((strncmp(yeschr, ans, i)) == 0)) 1603 return (1); 1604 1605 return (0); 1606 } 1607 1608 static int 1609 do_flash(int c, char *fpath, int force) 1610 { 1611 char devctl[MAXPATHLEN] = {0}; 1612 char buf[MAXPATHLEN] = {0}; 1613 int rv = 0; 1614 int imagetype; 1615 uint32_t nbytes = 0; 1616 uint32_t chksum; 1617 uint8_t *rombuf = NULL; 1618 char cwd[MAXPATHLEN]; 1619 1620 /* 1621 * Read fw file 1622 */ 1623 rv = readfile(fpath, &rombuf, &nbytes, &chksum); 1624 if (rv != 0) { 1625 return (FAILURE); 1626 } 1627 1628 (void) getcwd(cwd, sizeof (cwd)); 1629 1630 (void) chdir(DEVDIR); 1631 1632 /* Get link from "/dev/cfg" */ 1633 (void) snprintf(buf, sizeof (buf), "/dev/cfg/c%d", c); 1634 if (get_link_path(buf, devctl) != 0) { 1635 (void) fprintf(stderr, 1636 gettext("Invalid controller '%d'\n"), c); 1637 return (INVALID_ARG); 1638 } 1639 1640 /* Check File */ 1641 rv = checkfile(rombuf, nbytes, chksum, &imagetype); 1642 if (rv != 0) { 1643 return (FAILURE); 1644 } 1645 1646 /* Confirm */ 1647 if (!force) { 1648 (void) fprintf(stderr, gettext("Update flash image on " 1649 "controller %d (%s/%s)? "), c, yeschr, nochr); 1650 if (!yes()) { 1651 (void) fprintf(stderr, gettext("Controller %d not " 1652 "flashed.\n\n"), c); 1653 return (SUCCESS); 1654 } 1655 } 1656 1657 /* Do Flash */ 1658 if (updateflash(rombuf, nbytes, devctl)) { 1659 (void) fprintf(stderr, gettext("Flash not updated on " 1660 "Controller %d.\n\n"), c); 1661 return (INVALID_ARG); 1662 } 1663 (void) printf(gettext("Flash updated successfully.\n\n")); 1664 return (SUCCESS); 1665 } 1666 1667 static int 1668 fully_numeric(char *str) 1669 { 1670 int size = strlen(str); 1671 int i; 1672 1673 for (i = 0; i < size; i++) { 1674 if (i == 0 && str[i] == '-' && size != 1) 1675 continue; 1676 if (!isdigit(str[i])) 1677 return (0); 1678 } 1679 return (1); 1680 } 1681 1682 /* 1683 * Useful parsing macros 1684 */ 1685 #define must_be(s, c) if (*s++ != c) return (0) 1686 #define skip_digits(s) while (isdigit(*s)) s++ 1687 1688 /* 1689 * Return true if a name is in the internal canonical form 1690 */ 1691 static int 1692 canonical_name(char *name) 1693 { 1694 must_be(name, 'c'); 1695 skip_digits(name); 1696 if (*name == 't') { 1697 name++; 1698 skip_digits(name); 1699 } 1700 must_be(name, 'd'); 1701 skip_digits(name); 1702 return (*name == 0); 1703 } 1704 1705 int 1706 main(int argc, char **argv) 1707 { 1708 int rv = SUCCESS; 1709 int i, c; 1710 int findex = DO_HW_RAID_INFO; 1711 int controller; 1712 char *disks[N_DISKS] = {0}; 1713 char *darg; 1714 char *farg; 1715 char *rarg; 1716 char *progname; 1717 1718 int l_flag = 0; 1719 int c_flag = 0; 1720 int d_flag = 0; 1721 int f_flag = 0; 1722 int F_flag = 0; 1723 int r_flag = 0; 1724 int no_flags = 1; 1725 int r = RAID_MIRROR; /* default raid level is 1 */ 1726 char *current_dir; 1727 1728 (void) setlocale(LC_ALL, ""); 1729 (void) textdomain(TEXT_DOMAIN); 1730 1731 if (geteuid() != 0) { 1732 (void) fprintf(stderr, gettext("Must be root.\n")); 1733 exit(1); 1734 } 1735 1736 if ((progname = strrchr(argv[0], '/')) == NULL) 1737 progname = argv[0]; 1738 else 1739 progname++; 1740 1741 raids = NULL; 1742 1743 (void) strncpy(yeschr, nl_langinfo(YESSTR), SCHAR_MAX + 1); 1744 (void) strncpy(nochr, nl_langinfo(NOSTR), SCHAR_MAX + 1); 1745 1746 while ((c = getopt(argc, argv, "cr:lfd:F:")) != EOF) { 1747 switch (c) { 1748 case 'c': 1749 if (argc < 4) 1750 usage(progname); 1751 findex = DO_HW_RAID_CREATE; 1752 c_flag = 1; 1753 no_flags = 0; 1754 break; 1755 case 'r': 1756 rarg = optarg; 1757 r = atoi(rarg); 1758 if ((r != RAID_STRIPE) && (r != RAID_MIRROR)) 1759 usage(progname); 1760 r_flag = 1; 1761 break; 1762 case 'd': 1763 darg = optarg; 1764 d_flag = 1; 1765 findex = DO_HW_RAID_DELETE; 1766 no_flags = 0; 1767 break; 1768 case 'l': 1769 findex = DO_HW_RAID_INFO; 1770 l_flag = 1; 1771 no_flags = 0; 1772 break; 1773 case 'F': 1774 findex = DO_HW_RAID_FLASH; 1775 farg = optarg; 1776 F_flag = 1; 1777 no_flags = 0; 1778 break; 1779 case 'f': 1780 f_flag = 1; 1781 no_flags = 0; 1782 break; 1783 case '?': 1784 default: 1785 usage(progname); 1786 } 1787 } 1788 1789 if (no_flags && argc > 1) 1790 usage(progname); 1791 1792 /* compatibility rules */ 1793 if (c_flag && d_flag) 1794 usage(progname); 1795 if (l_flag && (d_flag || c_flag || f_flag || F_flag || r_flag)) 1796 usage(progname); 1797 if (F_flag && (d_flag || c_flag || l_flag || r_flag)) 1798 usage(progname); 1799 1800 switch (findex) { 1801 case DO_HW_RAID_INFO: 1802 if (l_flag) { 1803 /* 1804 * "raidctl" makes argc == 1 1805 * "-l" makes argc == 2 1806 */ 1807 ctrl_nums = argc - 2; 1808 if (ctrl_nums != 0) { 1809 info_ctrl = (int **) 1810 malloc(ctrl_nums * sizeof (int)); 1811 if (info_ctrl == NULL) 1812 return (FAILURE); 1813 } 1814 for (i = 0; i < ctrl_nums; i++) { 1815 char *tmp = argv[i + 2]; 1816 1817 info_ctrl[i] = (int *)malloc(2 * sizeof (int)); 1818 if (info_ctrl[i] == NULL) { 1819 free(info_ctrl); 1820 return (FAILURE); 1821 } 1822 if (fully_numeric(tmp)) { 1823 (void) sscanf(tmp, "%d", 1824 &info_ctrl[i][INFO_CTRL]); 1825 info_ctrl[i][INFO_STATUS] = 1826 RAID_INVALID_CTRL; 1827 } else { 1828 (void) fprintf(stderr, 1829 gettext("Invalid controller '%s'\n"), 1830 tmp); 1831 info_ctrl[i][INFO_STATUS] = 1832 RAID_DONT_USE; 1833 } 1834 } 1835 } else if (argc > 1) { 1836 usage(progname); 1837 } 1838 1839 do_info(); 1840 break; 1841 case DO_HW_RAID_CREATE: 1842 for (i = 0; i < N_DISKS; i++) { 1843 int p = 2 + (r_flag * 2) + f_flag + i; 1844 1845 if (p == argc) 1846 break; 1847 1848 disks[i] = argv[p]; 1849 1850 if (!canonical_name(disks[i])) 1851 usage(progname); 1852 1853 /* no more than 2 disks for raid level 1 */ 1854 if ((r == RAID_MIRROR) && (i > 1)) 1855 usage(progname); 1856 } 1857 1858 rv = do_create(disks, r, f_flag); 1859 break; 1860 case DO_HW_RAID_DELETE: 1861 if (!canonical_name(darg)) 1862 usage(progname); 1863 1864 rv = do_delete(darg, f_flag); 1865 break; 1866 case DO_HW_RAID_FLASH: 1867 ctrl_nums = argc - f_flag - 3; 1868 if (ctrl_nums == 0) 1869 usage(progname); 1870 1871 current_dir = getcwd(NULL, MAXPATHLEN); 1872 1873 for (i = 0; i < ctrl_nums; i++) { 1874 char *tmp = argv[i + 3 + f_flag]; 1875 (void) chdir(current_dir); 1876 if (fully_numeric(tmp)) { 1877 (void) sscanf(tmp, "%d", &controller); 1878 rv = do_flash(controller, farg, f_flag); 1879 if (rv == FAILURE) 1880 break; 1881 } else { 1882 (void) fprintf(stderr, 1883 gettext("Invalid controller '%s'\n"), 1884 tmp); 1885 } 1886 } 1887 free(current_dir); 1888 break; 1889 default: 1890 usage(progname); 1891 } 1892 return (rv); 1893 } 1894