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