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