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 /* 23 * Copyright 2010 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #include <emlxs.h> 29 30 #ifdef DUMP_SUPPORT 31 32 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 33 EMLXS_MSG_DEF(EMLXS_DUMP_C); 34 35 /* ************************************************************************* */ 36 /* Utility functions */ 37 /* ************************************************************************* */ 38 39 static uint32_t 40 emlxs_menlo_set_mode( 41 emlxs_hba_t *hba, 42 uint32_t mode) 43 { 44 emlxs_port_t *port = &PPORT; 45 uint32_t cmd_size; 46 uint32_t rsp_size; 47 menlo_cmd_t *cmd_buf = NULL; 48 menlo_rsp_t *rsp_buf = NULL; 49 uint32_t rval = 0; 50 51 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 52 return (DFC_INVALID_ADAPTER); 53 } 54 55 cmd_size = sizeof (menlo_set_cmd_t); 56 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP); 57 58 rsp_size = 4; 59 rsp_buf = (menlo_rsp_t *)kmem_zalloc(rsp_size, KM_SLEEP); 60 61 cmd_buf->code = MENLO_CMD_SET_MODE; 62 cmd_buf->set.value1 = mode; 63 cmd_buf->set.value2 = 0; 64 65 #ifdef EMLXS_BIG_ENDIAN 66 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size); 67 #endif /* EMLXS_BIG_ENDIAN */ 68 69 if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size, 70 (uint8_t *)rsp_buf, &rsp_size)) { 71 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 72 "emlxs_menlo_set_mode: Unable to send command."); 73 goto done; 74 } 75 #ifdef EMLXS_BIG_ENDIAN 76 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size); 77 #endif /* EMLXS_BIG_ENDIAN */ 78 79 if (rsp_buf->code != 0) { 80 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 81 "emlxs_menlo_set_mode: Menlo command error. code=%d.\n", 82 rsp_buf->code); 83 } 84 85 rval = rsp_buf->code; 86 87 done: 88 89 if (cmd_buf) { 90 kmem_free(cmd_buf, sizeof (menlo_set_cmd_t)); 91 } 92 93 if (rsp_buf) { 94 kmem_free(rsp_buf, 4); 95 } 96 97 return (rval); 98 99 } /* emlxs_menlo_set_mode() */ 100 101 102 static uint32_t 103 emlxs_menlo_reset( 104 emlxs_hba_t *hba, 105 uint32_t firmware) 106 { 107 emlxs_port_t *port = &PPORT; 108 uint32_t cmd_size; 109 uint32_t rsp_size; 110 menlo_cmd_t *cmd_buf = NULL; 111 menlo_rsp_t *rsp_buf = NULL; 112 uint32_t rval = 0; 113 114 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 115 return (DFC_INVALID_ADAPTER); 116 } 117 118 cmd_size = sizeof (menlo_reset_cmd_t); 119 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP); 120 121 rsp_size = 4; 122 rsp_buf = (menlo_rsp_t *)kmem_zalloc(rsp_size, KM_SLEEP); 123 124 cmd_buf->code = MENLO_CMD_RESET; 125 cmd_buf->reset.firmware = firmware; 126 127 #ifdef EMLXS_BIG_ENDIAN 128 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size); 129 #endif /* EMLXS_BIG_ENDIAN */ 130 131 if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size, 132 (uint8_t *)rsp_buf, &rsp_size)) { 133 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 134 "emlxs_menlo_reset: Unable to send command."); 135 goto done; 136 } 137 #ifdef EMLXS_BIG_ENDIAN 138 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size); 139 #endif /* EMLXS_BIG_ENDIAN */ 140 141 if (rsp_buf->code != 0) { 142 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 143 "emlxs_menlo_reset: Menlo command error. code=%d.\n", 144 rsp_buf->code); 145 } 146 147 rval = rsp_buf->code; 148 149 done: 150 151 if (cmd_buf) { 152 kmem_free(cmd_buf, sizeof (menlo_reset_cmd_t)); 153 } 154 155 if (rsp_buf) { 156 kmem_free(rsp_buf, 4); 157 } 158 159 return (rval); 160 161 } /* emlxs_menlo_reset() */ 162 163 164 static uint32_t 165 emlxs_menlo_get_cfg( 166 emlxs_hba_t *hba, 167 menlo_get_config_rsp_t *rsp_buf, 168 uint32_t rsp_size) 169 { 170 emlxs_port_t *port = &PPORT; 171 uint32_t cmd_size; 172 menlo_cmd_t *cmd_buf = NULL; 173 uint32_t rval = 0; 174 175 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 176 return (DFC_INVALID_ADAPTER); 177 } 178 179 cmd_size = sizeof (menlo_get_cmd_t); 180 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP); 181 182 rsp_size = sizeof (menlo_get_config_rsp_t); 183 184 cmd_buf->code = MENLO_CMD_GET_CONFIG; 185 cmd_buf->get.context = 0; 186 cmd_buf->get.length = rsp_size; 187 188 #ifdef EMLXS_BIG_ENDIAN 189 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size); 190 #endif /* EMLXS_BIG_ENDIAN */ 191 192 if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size, 193 (uint8_t *)rsp_buf, &rsp_size)) { 194 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 195 "emlxs_menlo_get_cfg: Unable to send command."); 196 goto done; 197 } 198 #ifdef EMLXS_BIG_ENDIAN 199 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size); 200 #endif /* EMLXS_BIG_ENDIAN */ 201 202 if (rsp_buf->code != 0) { 203 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 204 "emlxs_menlo_get_cfg: Menlo command error. code=%d.\n", 205 rsp_buf->code); 206 } 207 208 rval = rsp_buf->code; 209 210 done: 211 212 if (cmd_buf) { 213 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t)); 214 } 215 216 return (rval); 217 218 } /* emlxs_menlo_get_cfg() */ 219 220 221 222 static uint32_t 223 emlxs_menlo_get_logcfg( 224 emlxs_hba_t *hba, 225 menlo_rsp_t *rsp_buf, 226 uint32_t rsp_size) 227 { 228 emlxs_port_t *port = &PPORT; 229 uint32_t cmd_size; 230 menlo_cmd_t *cmd_buf = NULL; 231 uint32_t rval = 0; 232 233 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 234 return (DFC_INVALID_ADAPTER); 235 } 236 237 cmd_size = sizeof (menlo_get_cmd_t); 238 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP); 239 240 cmd_buf->code = MENLO_CMD_GET_LOG_CONFIG; 241 cmd_buf->get.context = 0; 242 cmd_buf->get.length = rsp_size; 243 244 #ifdef EMLXS_BIG_ENDIAN 245 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size); 246 #endif /* EMLXS_BIG_ENDIAN */ 247 248 if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size, 249 (uint8_t *)rsp_buf, &rsp_size)) { 250 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 251 "emlxs_menlo_get_logcfg: Unable to send command."); 252 goto done; 253 } 254 #ifdef EMLXS_BIG_ENDIAN 255 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size); 256 #endif /* EMLXS_BIG_ENDIAN */ 257 258 if (rsp_buf->code != 0) { 259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 260 "emlxs_menlo_get_logcfg: Menlo command error. code=%d.\n", 261 rsp_buf->code); 262 } 263 264 rval = rsp_buf->code; 265 266 done: 267 268 if (cmd_buf) { 269 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t)); 270 } 271 272 return (rval); 273 274 } /* emlxs_menlo_get_logcfg() */ 275 276 277 static uint32_t 278 emlxs_menlo_get_log( 279 emlxs_hba_t *hba, 280 uint32_t id, 281 menlo_rsp_t *rsp_buf, 282 uint32_t rsp_size) 283 { 284 emlxs_port_t *port = &PPORT; 285 uint32_t cmd_size; 286 menlo_cmd_t *cmd_buf = NULL; 287 uint32_t rval = 0; 288 289 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 290 return (DFC_INVALID_ADAPTER); 291 } 292 293 cmd_size = sizeof (menlo_get_cmd_t); 294 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP); 295 296 cmd_buf->code = MENLO_CMD_GET_LOG_DATA; 297 cmd_buf->get.context = id; 298 cmd_buf->get.length = rsp_size; 299 300 #ifdef EMLXS_BIG_ENDIAN 301 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size); 302 #endif /* EMLXS_BIG_ENDIAN */ 303 304 if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size, 305 (uint8_t *)rsp_buf, &rsp_size)) { 306 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 307 "emlxs_menlo_get_log: Unable to send command."); 308 goto done; 309 } 310 #ifdef EMLXS_BIG_ENDIAN 311 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size); 312 #endif /* EMLXS_BIG_ENDIAN */ 313 314 if (rsp_buf->code != 0) { 315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 316 "emlxs_menlo_get_log: Menlo command error. code=%d.\n", 317 rsp_buf->code); 318 } 319 320 rval = rsp_buf->code; 321 322 done: 323 324 if (cmd_buf) { 325 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t)); 326 } 327 328 return (rval); 329 330 } /* emlxs_menlo_get_log() */ 331 332 333 static uint32_t 334 emlxs_menlo_get_paniclog( 335 emlxs_hba_t *hba, 336 menlo_rsp_t *rsp_buf, 337 uint32_t rsp_size) 338 { 339 emlxs_port_t *port = &PPORT; 340 uint32_t cmd_size; 341 menlo_cmd_t *cmd_buf = NULL; 342 uint32_t rval = 0; 343 344 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 345 return (DFC_INVALID_ADAPTER); 346 } 347 348 cmd_size = sizeof (menlo_get_cmd_t); 349 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP); 350 351 cmd_buf->code = MENLO_CMD_GET_PANIC_LOG; 352 cmd_buf->get.context = 0; 353 cmd_buf->get.length = rsp_size; 354 355 #ifdef EMLXS_BIG_ENDIAN 356 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size); 357 #endif /* EMLXS_BIG_ENDIAN */ 358 359 if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size, 360 (uint8_t *)rsp_buf, &rsp_size)) { 361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 362 "emlxs_menlo_get_paniclog: Unable to send command."); 363 goto done; 364 } 365 #ifdef EMLXS_BIG_ENDIAN 366 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size); 367 #endif /* EMLXS_BIG_ENDIAN */ 368 369 if (rsp_buf->code != 0) { 370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 371 "emlxs_menlo_get_paniclog: Menlo command error. code=%d.\n", 372 rsp_buf->code); 373 } 374 375 rval = rsp_buf->code; 376 377 done: 378 379 if (cmd_buf) { 380 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t)); 381 } 382 383 return (rval); 384 385 } /* emlxs_menlo_get_paniclog() */ 386 387 388 389 390 extern void 391 emlxs_fflush( 392 emlxs_file_t *fp) 393 { 394 uint32_t offset; 395 396 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer); 397 398 if (offset > fp->size) { 399 fp->ptr = fp->buffer + fp->size; 400 } 401 402 return; 403 404 } /* emlxs_fflush() */ 405 406 407 extern uint32_t 408 emlxs_ftell( 409 emlxs_file_t *fp) 410 { 411 uint32_t offset; 412 413 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer); 414 415 return (offset); 416 417 } /* emlxs_ftell() */ 418 419 420 static void 421 emlxs_fputc( 422 uint8_t value, 423 emlxs_file_t *fp) 424 { 425 uint32_t offset; 426 427 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer); 428 429 if ((offset + 1) <= fp->size) { 430 *fp->ptr++ = value; 431 } 432 433 return; 434 435 } /* emlxs_fputc() */ 436 437 438 static uint32_t 439 emlxs_fwrite( 440 uint8_t *buffer, 441 uint32_t size, 442 uint32_t nitems, 443 emlxs_file_t *fp) 444 { 445 uint32_t offset; 446 uint32_t length; 447 448 length = size * nitems; 449 450 if (length) { 451 offset = 452 (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer); 453 454 if ((offset + length) > fp->size) { 455 length = fp->size - offset; 456 } 457 458 if (length) { 459 bcopy(buffer, fp->ptr, length); 460 fp->ptr += length; 461 } 462 } 463 464 return (length); 465 466 } /* emlxs_fwrite() */ 467 468 469 static uint32_t 470 emlxs_fprintf( 471 emlxs_file_t *fp, 472 const char *fmt, ...) 473 { 474 va_list valist; 475 char va_str[1024]; 476 uint32_t length; 477 478 va_start(valist, fmt); 479 (void) vsprintf(va_str, fmt, valist); 480 va_end(valist); 481 482 length = emlxs_fwrite((uint8_t *)va_str, strlen(va_str), 1, fp); 483 484 return (length); 485 486 } /* emlxs_fprintf() */ 487 488 489 extern emlxs_file_t * 490 emlxs_fopen( 491 emlxs_hba_t *hba, 492 uint32_t file_type) 493 { 494 emlxs_file_t *fp; 495 496 switch (file_type) { 497 case EMLXS_TXT_FILE: 498 fp = &hba->dump_txtfile; 499 fp->size = EMLXS_TXT_FILE_SIZE; 500 break; 501 502 case EMLXS_DMP_FILE: 503 fp = &hba->dump_dmpfile; 504 fp->size = EMLXS_DMP_FILE_SIZE; 505 break; 506 507 case EMLXS_CEE_FILE: 508 fp = &hba->dump_ceefile; 509 fp->size = EMLXS_CEE_FILE_SIZE; 510 break; 511 512 default: 513 return (NULL); 514 } 515 516 /* Make sure it is word aligned */ 517 fp->size &= 0xFFFFFFFC; 518 519 if (!fp->buffer) { 520 fp->buffer = 521 (uint8_t *)kmem_zalloc(fp->size, KM_SLEEP); 522 523 } else { 524 bzero(fp->buffer, fp->size); 525 } 526 527 fp->ptr = fp->buffer; 528 529 return (fp); 530 531 } /* emlxs_fopen() */ 532 533 534 extern uint32_t 535 emlxs_fclose( 536 emlxs_file_t *fp) 537 { 538 uint32_t offset; 539 540 if (fp == NULL) { 541 return (0); 542 } 543 544 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer); 545 offset = offset % 4; 546 547 switch (offset) { 548 case 0: 549 break; 550 551 case 1: 552 *fp->ptr++ = 0; 553 *fp->ptr++ = 0; 554 *fp->ptr++ = 0; 555 break; 556 557 case 2: 558 *fp->ptr++ = 0; 559 *fp->ptr++ = 0; 560 break; 561 562 case 3: 563 *fp->ptr++ = 0; 564 break; 565 } 566 567 return (0); 568 569 } /* emlxs_fclose() */ 570 571 572 static void 573 emlxs_fdelete( 574 emlxs_file_t *fp) 575 { 576 if (fp == NULL) { 577 return; 578 } 579 580 if (fp->buffer && fp->size) { 581 kmem_free(fp->buffer, fp->size); 582 } 583 584 fp->buffer = NULL; 585 fp->ptr = NULL; 586 fp->size = 0; 587 588 return; 589 590 } /* emlxs_fdelete() */ 591 592 593 /* This builds a single core buffer for the IOCTL interface */ 594 extern uint32_t 595 emlxs_get_dump( 596 emlxs_hba_t *hba, 597 uint8_t *buffer, 598 uint32_t *buflen) 599 { 600 emlxs_port_t *port = &PPORT; 601 int32_t i; 602 int32_t size; 603 int32_t count; 604 uint32_t size_dmp; 605 uint32_t size_txt; 606 uint32_t size_cee; 607 emlxs_file_t *fp_txt; 608 emlxs_file_t *fp_dmp; 609 emlxs_file_t *fp_cee; 610 uint32_t *wptr; 611 uint8_t *bptr; 612 613 if (!buflen) { 614 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 615 "emlxs_get_dump: Buffer length = 0"); 616 return (1); 617 } 618 619 fp_txt = &hba->dump_txtfile; 620 fp_dmp = &hba->dump_dmpfile; 621 fp_cee = &hba->dump_ceefile; 622 623 size_txt = emlxs_ftell(fp_txt); 624 size_dmp = emlxs_ftell(fp_dmp); 625 size_cee = emlxs_ftell(fp_cee); 626 627 size = 0; 628 count = 0; 629 if (size_txt) { 630 count++; 631 size += size_txt + 8; 632 } 633 if (size_dmp) { 634 count++; 635 size += size_dmp + 8; 636 } 637 if (size_cee) { 638 count++; 639 size += size_cee + 8; 640 } 641 642 if (size) { 643 size += 4; 644 } 645 646 if (!buffer) { 647 goto done; 648 } 649 650 bzero(buffer, *buflen); 651 652 if (*buflen < size) { 653 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 654 "emlxs_get_dump: Buffer length too small. %d < %d", 655 *buflen, size); 656 657 *buflen = 0; 658 return (1); 659 } 660 661 wptr = (uint32_t *)buffer; 662 wptr[0] = count; 663 i = 1; 664 665 if (size_txt) { 666 wptr[i++] = EMLXS_TXT_FILE_ID; 667 wptr[i++] = size_txt; 668 } 669 670 if (size_dmp) { 671 wptr[i++] = EMLXS_DMP_FILE_ID; 672 wptr[i++] = size_dmp; 673 } 674 675 if (size_cee) { 676 if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 677 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 678 wptr[i++] = EMLXS_FAT_FILE_ID; 679 } else { 680 wptr[i++] = EMLXS_CEE_FILE_ID; 681 } 682 683 wptr[i++] = size_cee; 684 } 685 686 bptr = (uint8_t *)&wptr[i]; 687 688 if (size_txt) { 689 bcopy(fp_txt->buffer, bptr, size_txt); 690 bptr += size_txt; 691 } 692 693 if (size_dmp) { 694 bcopy(fp_dmp->buffer, bptr, size_dmp); 695 bptr += size_dmp; 696 } 697 698 if (size_cee) { 699 bcopy(fp_cee->buffer, bptr, size_cee); 700 bptr += size_cee; 701 } 702 703 done: 704 705 *buflen = size; 706 707 /* printf("Done. buflen=%d \n", *buflen); */ 708 709 return (0); 710 711 } /* emlxs_get_dump() */ 712 713 714 static uint32_t 715 emlxs_read_cfg_region( 716 emlxs_hba_t *hba, 717 uint32_t Identifier, 718 uint32_t ByteCount, 719 uint32_t *pRetByteCount, 720 uint8_t *pBuffer) 721 { 722 emlxs_port_t *port = &PPORT; 723 MAILBOXQ *mbq; 724 uint32_t ByteCountRem; /* remaining portion of original byte count */ 725 uint32_t ByteCountReq; /* requested byte count for a particular dump */ 726 uint32_t CopyCount; /* bytes to copy after each successful dump */ 727 uint32_t Offset; /* Offset into Config Region, for each dump */ 728 uint8_t *pLocalBuf; /* ptr to buffer to receive each dump */ 729 730 mbq = 731 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP); 732 733 pLocalBuf = pBuffer; /* init local pointer to caller's buffer */ 734 Offset = 0; /* start at offset 0 */ 735 *pRetByteCount = 0; /* init returned byte count */ 736 CopyCount = 0; 737 738 for (ByteCountRem = ByteCount; ByteCountRem > 0; 739 ByteCountRem -= CopyCount) { 740 741 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 742 MAILBOX4 *mb = (MAILBOX4 *)mbq; 743 744 ByteCountReq = 745 (ByteCountRem < hba->sli.sli4.dump_region.size) ? 746 ByteCountRem : hba->sli.sli4.dump_region.size; 747 748 /* Clear the local dump_region */ 749 bzero(hba->sli.sli4.dump_region.virt, 750 hba->sli.sli4.dump_region.size); 751 752 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 753 754 mb->mbxCommand = MBX_DUMP_MEMORY; 755 mb->un.varDmp4.type = DMP_NV_PARAMS; 756 mb->un.varDmp4.entry_index = Offset; 757 mb->un.varDmp4.region_id = Identifier; 758 759 mb->un.varDmp4.available_cnt = ByteCountReq; 760 mb->un.varDmp4.addrHigh = 761 PADDR_HI(hba->sli.sli4.dump_region.phys); 762 mb->un.varDmp4.addrLow = 763 PADDR_LO(hba->sli.sli4.dump_region.phys); 764 mb->un.varDmp4.rsp_cnt = 0; 765 766 mb->mbxOwner = OWN_HOST; 767 mbq->mbox_cmpl = NULL; 768 769 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 770 MBX_SUCCESS) { 771 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 772 "Unable to read config region. id=%x "\ 773 "offset=%x status=%x", 774 Identifier, Offset, mb->mbxStatus); 775 776 kmem_free(mbq, sizeof (MAILBOXQ)); 777 return (1); 778 } 779 780 CopyCount = mb->un.varDmp4.rsp_cnt; 781 782 /* if no more data returned */ 783 if (CopyCount == 0) { 784 break; 785 } 786 787 if (CopyCount > ByteCountReq) { 788 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 789 "emlxs_read_cfg_region: " \ 790 "Byte count too big. %d > %d\n", 791 CopyCount, ByteCountReq); 792 793 CopyCount = ByteCountReq; 794 } 795 796 bcopy((uint8_t *)hba->sli.sli4.dump_region.virt, 797 pLocalBuf, CopyCount); 798 799 } else { 800 MAILBOX *mb = (MAILBOX *)mbq; 801 802 ByteCountReq = 803 (ByteCountRem < DUMP_BC_MAX) ? ByteCountRem : 804 DUMP_BC_MAX; 805 806 bzero((void *)mb, MAILBOX_CMD_BSIZE); 807 808 mb->mbxCommand = MBX_DUMP_MEMORY; 809 mb->un.varDmp.type = DMP_NV_PARAMS; 810 mb->un.varDmp.cv = 1; 811 mb->un.varDmp.region_id = Identifier; 812 mb->un.varDmp.entry_index = Offset; 813 mb->un.varDmp.word_cnt = ByteCountReq / 4; 814 mb->mbxOwner = OWN_HOST; 815 mbq->mbox_cmpl = NULL; 816 817 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 818 MBX_SUCCESS) { 819 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 820 "Unable to read config region. id=%x "\ 821 "offset=%x status=%x", 822 Identifier, Offset, mb->mbxStatus); 823 824 kmem_free(mbq, sizeof (MAILBOXQ)); 825 return (1); 826 } 827 828 /* Note: for Type 2/3 Dumps, varDmp.word_cnt is */ 829 /* actually a byte count. */ 830 CopyCount = mb->un.varDmp.word_cnt; 831 832 /* if no more data returned */ 833 if (CopyCount == 0) { 834 break; 835 } 836 837 if (CopyCount > ByteCountReq) { 838 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 839 "emlxs_read_cfg_region: " \ 840 "Byte count too big. %d > %d\n", 841 CopyCount, ByteCountReq); 842 843 CopyCount = ByteCountReq; 844 } 845 846 bcopy((uint8_t *)&mb->un.varDmp.resp_offset, pLocalBuf, 847 CopyCount); 848 } 849 850 pLocalBuf += CopyCount; 851 Offset += CopyCount; 852 *pRetByteCount += CopyCount; 853 } 854 855 return (0); 856 857 } /* emlxs_read_cfg_region() */ 858 859 860 861 /* ************************************************************************* */ 862 /* ************************************************************************* */ 863 /* Dump Generators, Low-Level */ 864 /* ************************************************************************* */ 865 /* ************************************************************************* */ 866 867 static uint32_t 868 emlxs_dump_string_txtfile( 869 emlxs_file_t *fpTxtFile, 870 char *pString, 871 char *pSidLegend, 872 char *pLidLegend, 873 uint32_t pure) 874 { 875 876 if (!fpTxtFile) { 877 return (1); 878 } 879 880 if (pSidLegend && pLidLegend) { 881 (void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend, 882 pLidLegend); 883 884 if (pure == 0) { 885 emlxs_fputc(' ', fpTxtFile); 886 } 887 888 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1, 889 fpTxtFile); 890 891 if (pure == 0) { 892 emlxs_fputc('\n', fpTxtFile); 893 emlxs_fputc('\n', fpTxtFile); 894 } 895 } else { 896 if (pure == 0) { 897 emlxs_fputc(' ', fpTxtFile); 898 } 899 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1, 900 fpTxtFile); 901 } 902 903 emlxs_fflush(fpTxtFile); 904 905 return (0); 906 907 } /* emlxs_dump_string_txtfile() */ 908 909 910 static uint32_t 911 emlxs_dump_word_txtfile( 912 emlxs_file_t *fpTxtFile, 913 uint32_t *pBuffer, 914 uint32_t WordCount, 915 char *pSidLegend, 916 char *pLidLegend) 917 { 918 char buf1[256]; 919 char buf2[256]; 920 uint32_t *ptr; 921 uint32_t j; 922 923 if (!fpTxtFile) { 924 return (1); 925 } 926 927 /* Write Legend String to the TXT File */ 928 (void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend, pLidLegend); 929 930 /* Write the buffer to the TXT File */ 931 ptr = pBuffer; 932 933 for (j = 0; j < WordCount; j++) { 934 buf1[0] = 0; 935 buf2[0] = 0; 936 937 if ((j & 0x03) == 0) { 938 (void) sprintf(buf1, "\n%04x:", j * 4); 939 (void) strcat(buf2, buf1); 940 } 941 (void) sprintf(buf1, " %08x", ptr[j]); /* print 1 word */ 942 (void) strcat(buf2, buf1); 943 (void) emlxs_fwrite((uint8_t *)buf2, strlen(buf2), 1, 944 fpTxtFile); 945 } 946 947 emlxs_fputc('\n', fpTxtFile); 948 emlxs_fputc('\n', fpTxtFile); 949 emlxs_fflush(fpTxtFile); 950 return (0); 951 952 } /* emlxs_dump_word_txtfile() */ 953 954 955 956 957 static uint32_t 958 emlxs_dump_string_dmpfile( 959 emlxs_file_t *fpDmpFile, 960 char *pString, 961 uint8_t sid, 962 char *pSidLegend, 963 char *pLidLegend) 964 { 965 uint32_t length; 966 uint8_t byte; 967 uint32_t pos; 968 969 if (!fpDmpFile) { 970 return (1); 971 } 972 973 /* Write Legend SID to the DMP File */ 974 emlxs_fputc(SID_LEGEND, fpDmpFile); 975 976 /* Write Argument SID to the DMP File */ 977 emlxs_fputc(sid, fpDmpFile); 978 979 /* Write Legend String to the DMP File, including a Null Byte */ 980 (void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend); 981 emlxs_fputc(0, fpDmpFile); 982 983 /* Write Argument SID to the DMP File */ 984 emlxs_fputc(sid, fpDmpFile); 985 986 /* Write Buffer Length to the DMP File */ 987 length = (uint32_t)(strlen(pString) + 1); 988 #ifdef EMLXS_LITTLE_ENDIAN 989 byte = (uint8_t)(length & 0x0000FF); 990 emlxs_fputc(byte, fpDmpFile); 991 byte = (uint8_t)((length & 0x00FF00) >> 8); 992 emlxs_fputc(byte, fpDmpFile); 993 byte = (uint8_t)((length & 0xFF0000) >> 16); 994 emlxs_fputc(byte, fpDmpFile); 995 #endif /* EMLXS_LITTLE_ENDIAN */ 996 997 #ifdef EMLXS_BIG_ENDIAN 998 byte = (uint8_t)((length & 0xFF0000) >> 16); 999 emlxs_fputc(byte, fpDmpFile); 1000 byte = (uint8_t)((length & 0x00FF00) >> 8); 1001 emlxs_fputc(byte, fpDmpFile); 1002 byte = (uint8_t)(length & 0x0000FF); 1003 emlxs_fputc(byte, fpDmpFile); 1004 #endif /* EMLXS_BIG_ENDIAN */ 1005 1006 /* Write Argument String to the DMP File, including a Null Byte */ 1007 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1, fpDmpFile); 1008 emlxs_fputc(0, fpDmpFile); 1009 1010 emlxs_fflush(fpDmpFile); 1011 1012 #if CC_DUMP_ENABLE_PAD 1013 /* check file size.. pad as necessary */ 1014 pos = emlxs_ftell(fpDmpFile); 1015 switch (pos & 0x03) { 1016 case 0: 1017 break; 1018 case 1: 1019 emlxs_fputc(0, fpDmpFile); 1020 emlxs_fputc(0, fpDmpFile); 1021 emlxs_fputc(0, fpDmpFile); 1022 break; 1023 case 2: 1024 emlxs_fputc(0, fpDmpFile); 1025 emlxs_fputc(0, fpDmpFile); 1026 break; 1027 case 3: 1028 emlxs_fputc(0, fpDmpFile); 1029 break; 1030 } 1031 emlxs_fflush(fpDmpFile); 1032 #endif 1033 1034 return (0); 1035 1036 } /* emlxs_dump_string_dmpfile() */ 1037 1038 1039 /* ************************************************************************** */ 1040 /* emlxs_dump_word_dmpfile */ 1041 /* If little endian, just write the buffer normally. */ 1042 /* However, if Big Endian... Consider the following: */ 1043 /* Automatic Dump, initiated by driver, Port Offline (FW WarmStart Mode), */ 1044 /* Mailbox in SLIM. */ 1045 /* On-Demand Dump, initiated by utility, Port Online (FW Normal Mode), */ 1046 /* Mailbox in Host Memory. */ 1047 /* We use the same IOCTL to get the DUMP Data, for both cases. */ 1048 /* However, it normalizes the data before delivering it to us. */ 1049 /* In the Dump File, we must always write the data in native mode. */ 1050 /* So, if Big Endian, On-demand Dump, we must swap the words. */ 1051 /* ************************************************************************* */ 1052 /*ARGSUSED*/ 1053 extern uint32_t 1054 emlxs_dump_word_dmpfile( 1055 emlxs_file_t *fpDmpFile, 1056 uint8_t *pBuffer, 1057 uint32_t bufferLen, 1058 int fSwap) 1059 { 1060 uint32_t i; 1061 uint32_t *wptr; 1062 1063 if (!fpDmpFile) { 1064 return (1); 1065 } 1066 1067 wptr = (uint32_t *)pBuffer; 1068 for (i = 0; i < bufferLen / 4; i++, wptr++) { 1069 if (fSwap) { 1070 uint32_t w1; 1071 w1 = *wptr; 1072 *wptr = BE_SWAP32(w1); 1073 } 1074 1075 (void) emlxs_fwrite((uint8_t *)wptr, 4, 1, fpDmpFile); 1076 } 1077 1078 emlxs_fflush(fpDmpFile); 1079 1080 return (0); 1081 1082 } /* emlxs_dump_word_dmpfile() */ 1083 1084 1085 static uint32_t 1086 emlxs_dump_port_block( 1087 emlxs_file_t *fpDmpFile, 1088 uint8_t *pBuffer, 1089 uint32_t bufferLen, 1090 DUMP_TABLE_ENTRY entry, 1091 int fSwap) 1092 { 1093 uint32_t status; 1094 uint32_t w; 1095 uint8_t b; 1096 1097 if (!fpDmpFile) { 1098 return (1); 1099 } 1100 1101 /* Write Argument SID to the DMP File */ 1102 b = (uint8_t)entry.un.PortBlock.un.s.sid; 1103 emlxs_fputc(b, fpDmpFile); 1104 1105 #ifdef EMLXS_LITTLE_ENDIAN 1106 /* Write Buffer Length to the DMP File */ 1107 w = entry.un.PortBlock.un.s.bc; 1108 b = (uint8_t)(w & 0x000000FF); 1109 emlxs_fputc(b, fpDmpFile); 1110 b = (uint8_t)((w & 0x0000FF00) >> 8); 1111 emlxs_fputc(b, fpDmpFile); 1112 b = (uint8_t)((w & 0x00FF0000) >> 16); 1113 emlxs_fputc(b, fpDmpFile); 1114 1115 /* Write address to the DMP File */ 1116 w = entry.un.PortBlock.un.s.addr; 1117 b = (uint8_t)(w & 0x000000FF); 1118 emlxs_fputc(b, fpDmpFile); 1119 b = (uint8_t)((w & 0x0000FF00) >> 8); 1120 emlxs_fputc(b, fpDmpFile); 1121 b = (uint8_t)((w & 0x00FF0000) >> 16); 1122 emlxs_fputc(b, fpDmpFile); 1123 b = (uint8_t)((w & 0xFF000000) >> 24); 1124 emlxs_fputc(b, fpDmpFile); 1125 #endif /* EMLXS_LITTLE_ENDIAN */ 1126 1127 #ifdef EMLXS_BIG_ENDIAN 1128 /* Write Buffer Length to the DMP File */ 1129 w = entry.un.PortBlock.un.s.bc; 1130 b = (uint8_t)((w & 0x00FF0000) >> 16); 1131 emlxs_fputc(b, fpDmpFile); 1132 b = (uint8_t)((w & 0x0000FF00) >> 8); 1133 emlxs_fputc(b, fpDmpFile); 1134 b = (uint8_t)(w & 0x000000FF); 1135 emlxs_fputc(b, fpDmpFile); 1136 1137 /* Write address to the DMP File */ 1138 w = entry.un.PortBlock.un.s.addr; 1139 b = (uint8_t)((w & 0xFF000000) >> 24); 1140 emlxs_fputc(b, fpDmpFile); 1141 b = (uint8_t)((w & 0x00FF0000) >> 16); 1142 emlxs_fputc(b, fpDmpFile); 1143 b = (uint8_t)((w & 0x0000FF00) >> 8); 1144 emlxs_fputc(b, fpDmpFile); 1145 b = (uint8_t)(w & 0x000000FF); 1146 emlxs_fputc(b, fpDmpFile); 1147 #endif /* EMLXS_BIG_ENDIAN */ 1148 1149 status = 1150 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap); 1151 1152 emlxs_fflush(fpDmpFile); 1153 1154 return (status); 1155 1156 } /* emlxs_dump_port_block() */ 1157 1158 1159 static uint32_t 1160 emlxs_dump_port_struct( 1161 emlxs_file_t *fpDmpFile, 1162 uint8_t *pBuffer, 1163 uint32_t bufferLen, 1164 DUMP_TABLE_ENTRY entry, 1165 int fSwap) 1166 { 1167 uint32_t status; 1168 uint32_t w; 1169 uint8_t b; 1170 1171 if (!fpDmpFile) { 1172 return (1); 1173 } 1174 1175 /* Write Argument SID to the DMP File */ 1176 b = (uint8_t)entry.un.PortStruct.un.s.sid; 1177 emlxs_fputc(b, fpDmpFile); 1178 1179 /* Write Element Length to the DMP File */ 1180 b = (uint8_t)entry.un.PortStruct.un.s.length; 1181 emlxs_fputc(b, fpDmpFile); 1182 1183 #ifdef EMLXS_LITTLE_ENDIAN 1184 /* Write Element Count to the DMP File */ 1185 w = entry.un.PortStruct.un.s.count; 1186 b = (uint8_t)(w & 0x000000FF); 1187 emlxs_fputc(b, fpDmpFile); 1188 b = (uint8_t)((w & 0x0000FF00) >> 8); 1189 emlxs_fputc(b, fpDmpFile); 1190 1191 /* Write Address to the DMP File */ 1192 w = entry.un.PortStruct.un.s.addr; 1193 b = (uint8_t)(w & 0x000000FF); 1194 emlxs_fputc(b, fpDmpFile); 1195 b = (uint8_t)((w & 0x0000FF00) >> 8); 1196 emlxs_fputc(b, fpDmpFile); 1197 b = (uint8_t)((w & 0x00FF0000) >> 16); 1198 emlxs_fputc(b, fpDmpFile); 1199 b = (uint8_t)((w & 0xFF000000) >> 24); 1200 emlxs_fputc(b, fpDmpFile); 1201 #endif /* EMLXS_LITTLE_ENDIAN */ 1202 1203 #ifdef EMLXS_BIG_ENDIAN 1204 /* Write Element Count to the DMP File */ 1205 w = entry.un.PortStruct.un.s.count; 1206 b = (uint8_t)((w & 0x0000FF00) >> 8); 1207 emlxs_fputc(b, fpDmpFile); 1208 b = (uint8_t)(w & 0x000000FF); 1209 emlxs_fputc(b, fpDmpFile); 1210 1211 /* Write Address to the DMP File */ 1212 w = entry.un.PortStruct.un.s.addr; 1213 b = (uint8_t)((w & 0xFF000000) >> 24); 1214 emlxs_fputc(b, fpDmpFile); 1215 b = (uint8_t)((w & 0x00FF0000) >> 16); 1216 emlxs_fputc(b, fpDmpFile); 1217 b = (uint8_t)((w & 0x0000FF00) >> 8); 1218 emlxs_fputc(b, fpDmpFile); 1219 b = (uint8_t)(w & 0x000000FF); 1220 emlxs_fputc(b, fpDmpFile); 1221 #endif /* EMLXS_BIG_ENDIAN */ 1222 1223 status = 1224 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap); 1225 1226 emlxs_fflush(fpDmpFile); 1227 1228 return (status); 1229 1230 } /* emlxs_dump_port_struct() */ 1231 1232 1233 static uint32_t 1234 emlxs_dump_host_block( 1235 emlxs_file_t *fpDmpFile, 1236 uint8_t *pBuffer, 1237 uint32_t bufferLen, 1238 uint8_t sid, 1239 char *pSidLegend, 1240 char *pLidLegend, 1241 int fSwap) 1242 { 1243 uint32_t status; 1244 uint32_t length; 1245 uint8_t byte; 1246 1247 if (!fpDmpFile) { 1248 return (1); 1249 } 1250 1251 /* Write Legend SID to the DMP File */ 1252 emlxs_fputc(SID_LEGEND, fpDmpFile); 1253 1254 /* Write Argument SID to the DMP File */ 1255 emlxs_fputc(sid, fpDmpFile); 1256 1257 /* Write Legend String to the DMP File, including a Null Byte */ 1258 (void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend); 1259 emlxs_fputc(0, fpDmpFile); 1260 1261 /* Write Argument SID to the DMP File */ 1262 emlxs_fputc(sid, fpDmpFile); 1263 1264 /* Write Buffer Length to the DMP File */ 1265 length = bufferLen; 1266 #ifdef EMLXS_LITTLE_ENDIAN 1267 byte = (uint8_t)(length & 0x0000FF); 1268 emlxs_fputc(byte, fpDmpFile); 1269 byte = (uint8_t)((length & 0x00FF00) >> 8); 1270 emlxs_fputc(byte, fpDmpFile); 1271 byte = (uint8_t)((length & 0xFF0000) >> 16); 1272 emlxs_fputc(byte, fpDmpFile); 1273 #endif /* EMLXS_LITTLE_ENDIAN */ 1274 1275 #ifdef EMLXS_BIG_ENDIAN 1276 byte = (uint8_t)((length & 0xFF0000) >> 16); 1277 emlxs_fputc(byte, fpDmpFile); 1278 byte = (uint8_t)((length & 0x00FF00) >> 8); 1279 emlxs_fputc(byte, fpDmpFile); 1280 byte = (uint8_t)(length & 0x0000FF); 1281 emlxs_fputc(byte, fpDmpFile); 1282 #endif /* EMLXS_BIG_ENDIAN */ 1283 1284 status = 1285 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap); 1286 1287 emlxs_fflush(fpDmpFile); 1288 1289 return (status); 1290 1291 } /* emlxs_dump_host_block() */ 1292 1293 1294 static uint32_t 1295 emlxs_dump_host_struct( 1296 emlxs_file_t *fpDmpFile, 1297 uint8_t *pBuffer, 1298 uint32_t bufferLen, 1299 uint32_t elementLength, 1300 uint32_t elementCount, 1301 uint8_t sid, 1302 char *pSidLegend, 1303 char *pLidLegend, 1304 int fSwap) 1305 { 1306 uint32_t status; 1307 uint32_t w; 1308 uint8_t b; 1309 1310 if (!fpDmpFile) { 1311 return (1); 1312 } 1313 1314 /* Write Legend SID to the DMP File */ 1315 emlxs_fputc(SID_LEGEND, fpDmpFile); 1316 1317 /* Write Argument SID to the DMP File */ 1318 emlxs_fputc(sid, fpDmpFile); 1319 1320 /* Write Legend String to the DMP File, including a Null Byte */ 1321 (void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend); 1322 emlxs_fputc(0, fpDmpFile); 1323 1324 /* Write Argument SID to the DMP File */ 1325 emlxs_fputc(sid, fpDmpFile); 1326 1327 /* Write Element Length to the DMP File */ 1328 b = (uint8_t)elementLength; 1329 emlxs_fputc(b, fpDmpFile); 1330 1331 /* Write Element Count to the DMP File */ 1332 w = elementCount; 1333 #ifdef EMLXS_LITTLE_ENDIAN 1334 b = (uint8_t)(w & 0x000000FF); 1335 emlxs_fputc(b, fpDmpFile); 1336 b = (uint8_t)((w & 0x0000FF00) >> 8); 1337 emlxs_fputc(b, fpDmpFile); 1338 #endif /* EMLXS_LITTLE_ENDIAN */ 1339 1340 #ifdef EMLXS_BIG_ENDIAN 1341 b = (uint8_t)((w & 0x0000FF00) >> 8); 1342 emlxs_fputc(b, fpDmpFile); 1343 b = (uint8_t)(w & 0x000000FF); 1344 emlxs_fputc(b, fpDmpFile); 1345 #endif /* EMLXS_BIG_ENDIAN */ 1346 1347 status = 1348 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap); 1349 1350 emlxs_fflush(fpDmpFile); 1351 1352 return (status); 1353 1354 } /* emlxs_dump_host_struct() */ 1355 1356 1357 /* ************************************************************************* */ 1358 /* ************************************************************************* */ 1359 /* Dump Generators, Mid-Level */ 1360 /* ************************************************************************* */ 1361 /* ************************************************************************* */ 1362 1363 static uint32_t 1364 emlxs_dump_parm_table( 1365 emlxs_hba_t *hba, 1366 emlxs_file_t *fpTxtFile, 1367 emlxs_file_t *fpDmpFile) 1368 { 1369 emlxs_config_t *cfg = &CFG; 1370 uint32_t status; 1371 uint32_t i; 1372 1373 /* vars used to build the Dump String */ 1374 char *buf1; 1375 char *buf2; 1376 1377 buf1 = (char *)kmem_zalloc(8192, KM_SLEEP); 1378 buf2 = (char *)kmem_zalloc(8192, KM_SLEEP); 1379 1380 /* Driver Parameters Heading */ 1381 (void) sprintf(buf1, 1382 "IDX string Low "\ 1383 "High Def Cur Exp Dyn"); 1384 1385 /* Build the buffer containing all the Driver Params */ 1386 for (i = 0; i < NUM_CFG_PARAM; i++) { 1387 (void) sprintf(buf2, 1388 "\n %02x: %25s %8x %8x %8x %8x %4x %4x", i, 1389 cfg[i].string, cfg[i].low, cfg[i].hi, cfg[i].def, 1390 cfg[i].current, (cfg[i].flags & PARM_HIDDEN) ? 0 : 1, 1391 (cfg[i].flags & PARM_DYNAMIC) ? 1 : 0); 1392 1393 (void) strcat(buf1, buf2); 1394 } 1395 1396 status = 1397 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_DP_TABLE, 1398 LEGEND_NULL, 0); 1399 1400 status = 1401 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_DP_TABLE, 1402 LEGEND_DP_TABLE, LEGEND_NULL); 1403 1404 kmem_free(buf1, 8192); 1405 kmem_free(buf2, 8192); 1406 1407 return (status); 1408 1409 } /* emlxs_dump_parm_table() */ 1410 1411 1412 static uint32_t 1413 emlxs_dump_model( 1414 emlxs_hba_t *hba, 1415 emlxs_file_t *fpTxtFile, 1416 emlxs_file_t *fpDmpFile) 1417 { 1418 emlxs_vpd_t *vpd = &VPD; 1419 uint32_t status; 1420 1421 /* vars used to build the Dump String */ 1422 char buf1[512]; 1423 char buf2[512]; 1424 1425 /* Write the Model into the buffer */ 1426 (void) sprintf(buf2, "%s", vpd->model); 1427 (void) strcpy(buf1, "Model: "); 1428 (void) strcat(buf1, buf2); 1429 1430 /* Write the Model Description into the buffer */ 1431 (void) sprintf(buf2, "%s", vpd->model_desc); 1432 (void) strcat(buf1, "\n Description: "); 1433 (void) strcat(buf1, buf2); 1434 1435 status = 1436 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO, 1437 LEGEND_HBA_MODEL, 0); 1438 1439 status = 1440 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO, 1441 LEGEND_HBA_INFO, LEGEND_HBA_MODEL); 1442 1443 return (status); 1444 1445 } /* emlxs_dump_model() */ 1446 1447 1448 static uint32_t 1449 emlxs_dump_wwn( 1450 emlxs_hba_t *hba, 1451 emlxs_file_t *fpTxtFile, 1452 emlxs_file_t *fpDmpFile) 1453 { 1454 uint32_t status; 1455 1456 /* vars used to build the Dump String */ 1457 char buf1[512]; 1458 char buf2[512]; 1459 int i; 1460 uint8_t *p; 1461 1462 /* Write the WWPN into the buffer */ 1463 (void) strcpy(buf1, "Port WWN: "); 1464 p = (uint8_t *)&hba->wwpn; 1465 for (i = 0; i < 7; i++) { 1466 (void) sprintf(buf2, "%02x:", *p++); 1467 (void) strcat(buf1, buf2); 1468 } 1469 (void) sprintf(buf2, "%02x", *p++); 1470 (void) strcat(buf1, buf2); 1471 1472 /* Write the WWNN into the buffer */ 1473 (void) strcat(buf1, "\n Node WWN: "); 1474 p = (uint8_t *)&hba->wwnn; 1475 for (i = 0; i < 7; i++) { 1476 (void) sprintf(buf2, "%02x:", *p++); 1477 (void) strcat(buf1, buf2); 1478 } 1479 (void) sprintf(buf2, "%02x", *p++); 1480 (void) strcat(buf1, buf2); 1481 1482 status = 1483 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO, 1484 LEGEND_HBA_WWN, 0); 1485 1486 status = 1487 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO, 1488 LEGEND_HBA_INFO, LEGEND_HBA_WWN); 1489 1490 return (status); 1491 1492 } /* emlxs_dump_wwn() */ 1493 1494 1495 static uint32_t 1496 emlxs_dump_serial_number( 1497 emlxs_hba_t *hba, 1498 emlxs_file_t *fpTxtFile, 1499 emlxs_file_t *fpDmpFile) 1500 { 1501 emlxs_vpd_t *vpd = &VPD; 1502 uint32_t status; 1503 1504 /* vars used to build the Dump String */ 1505 char buf1[512]; 1506 char buf2[512]; 1507 1508 /* Write the Serial Number into the buffer */ 1509 (void) sprintf(buf2, "%s", vpd->serial_num); 1510 (void) strcpy(buf1, LEGEND_HBA_SN); 1511 (void) strcat(buf1, ": "); 1512 (void) strcat(buf1, buf2); 1513 1514 status = 1515 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO, 1516 LEGEND_HBA_SN, 0); 1517 1518 status = 1519 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO, 1520 LEGEND_HBA_INFO, LEGEND_HBA_SN); 1521 1522 return (status); 1523 1524 } /* emlxs_dump_serial_number() */ 1525 1526 1527 static uint32_t 1528 emlxs_dump_fw_version( 1529 emlxs_hba_t *hba, 1530 emlxs_file_t *fpTxtFile, 1531 emlxs_file_t *fpDmpFile) 1532 { 1533 emlxs_vpd_t *vpd = &VPD; 1534 uint32_t status; 1535 1536 char *buf1; 1537 char *buf2; 1538 uint32_t buf1_size; 1539 uint32_t buf2_size; 1540 1541 buf1_size = 1024; 1542 buf2_size = 1024; 1543 1544 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 1545 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 1546 1547 /* Write the Firmware Version into the buffer */ 1548 (void) sprintf(buf2, "%s", vpd->fw_version); 1549 (void) strcpy(buf1, LEGEND_HBA_FW_VERSION); 1550 (void) strcat(buf1, ": "); 1551 (void) strcat(buf1, buf2); 1552 1553 /* Write the Operational FW Version into the buffer */ 1554 (void) sprintf(buf2, "%s", vpd->opFwName); 1555 (void) strcat(buf1, "\n "); 1556 (void) strcat(buf1, LEGEND_HBA_FW_OPVERSION); 1557 (void) strcat(buf1, ": "); 1558 (void) strcat(buf1, buf2); 1559 1560 /* Write the SLI-1 FW Version into the buffer */ 1561 (void) sprintf(buf2, "%s", vpd->sli1FwName); 1562 (void) strcat(buf1, "\n "); 1563 (void) strcat(buf1, LEGEND_HBA_FW_SLI1VERSION); 1564 (void) strcat(buf1, ": "); 1565 (void) strcat(buf1, buf2); 1566 1567 /* Write the SLI-2 FW Version into the buffer */ 1568 (void) sprintf(buf2, "%s", vpd->sli2FwName); 1569 (void) strcat(buf1, "\n "); 1570 (void) strcat(buf1, LEGEND_HBA_FW_SLI2VERSION); 1571 (void) strcat(buf1, ": "); 1572 (void) strcat(buf1, buf2); 1573 1574 /* Write the SLI-3 FW Version into the buffer */ 1575 (void) sprintf(buf2, "%s", vpd->sli3FwName); 1576 (void) strcat(buf1, "\n "); 1577 (void) strcat(buf1, LEGEND_HBA_FW_SLI3VERSION); 1578 (void) strcat(buf1, ": "); 1579 (void) strcat(buf1, buf2); 1580 1581 /* Write the Kernel FW Version into the buffer */ 1582 (void) sprintf(buf2, "%s", vpd->postKernName); 1583 (void) strcat(buf1, "\n "); 1584 (void) strcat(buf1, LEGEND_HBA_FW_KERNELVERSION); 1585 (void) strcat(buf1, ": "); 1586 (void) strcat(buf1, buf2); 1587 1588 status = 1589 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO, 1590 LEGEND_HBA_FW_VERSION, 0); 1591 1592 status = 1593 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO, 1594 LEGEND_HBA_INFO, LEGEND_HBA_FW_VERSION); 1595 1596 kmem_free(buf1, buf1_size); 1597 kmem_free(buf2, buf2_size); 1598 1599 return (status); 1600 1601 } /* emlxs_dump_fw_version() */ 1602 1603 1604 static uint32_t 1605 emlxs_dump_boot_version( 1606 emlxs_hba_t *hba, 1607 emlxs_file_t *fpTxtFile, 1608 emlxs_file_t *fpDmpFile) 1609 { 1610 emlxs_vpd_t *vpd = &VPD; 1611 uint32_t status; 1612 uint32_t state; 1613 1614 char *buf1; 1615 char *buf2; 1616 uint32_t buf1_size; 1617 uint32_t buf2_size; 1618 1619 buf1_size = 1024; 1620 buf2_size = 1024; 1621 1622 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 1623 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 1624 1625 #ifdef EMLXS_SPARC 1626 if (strcmp(vpd->fcode_version, "none") == 0) 1627 #else 1628 if (strcmp(vpd->boot_version, "none") == 0) 1629 #endif /* EMLXS_SPARC */ 1630 { 1631 state = 2; /* BOOT_BIOS_NOT_PRESENT */ 1632 } else { 1633 state = emlxs_boot_code_state(hba); 1634 } 1635 1636 /* Write the Boot Bios State into the buffer */ 1637 (void) sprintf(buf2, " %d", state); 1638 (void) strcpy(buf1, LEGEND_HBA_BB_STATE); 1639 (void) strcat(buf1, ": "); 1640 (void) strcat(buf1, buf2); 1641 1642 /* Write the Boot Bios Version into the buffer */ 1643 if (state == 2) { 1644 (void) sprintf(buf2, "%s", "unknown"); 1645 } else { 1646 #ifdef EMLXS_SPARC 1647 (void) sprintf(buf2, "%s (FCode)", vpd->fcode_version); 1648 #else 1649 (void) sprintf(buf2, "%s", vpd->boot_version); 1650 #endif /* EMLXS_SPARC */ 1651 } 1652 1653 (void) strcat(buf1, "\n "); 1654 (void) strcat(buf1, LEGEND_HBA_BB_VERSION); 1655 (void) strcat(buf1, ": "); 1656 (void) strcat(buf1, buf2); 1657 1658 status = 1659 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO, 1660 LEGEND_HBA_BB_VERSION, 0); 1661 1662 status = 1663 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO, 1664 LEGEND_HBA_INFO, LEGEND_HBA_BB_VERSION); 1665 1666 kmem_free(buf1, buf1_size); 1667 kmem_free(buf2, buf2_size); 1668 1669 return (status); 1670 1671 } /* emlxs_dump_boot_version() */ 1672 1673 1674 /* ARGSUSED */ 1675 static uint32_t 1676 emlxs_dump_cfg_region4_decoded( 1677 emlxs_hba_t *hba, 1678 emlxs_file_t *fpTxtFile, 1679 char *pLidLegend, 1680 DUMP_WAKE_UP_PARAMS *pBuffer, 1681 uint32_t ByteCount) 1682 { 1683 uint32_t status; 1684 char *buf1; /* text buffer */ 1685 char *buf2; /* text buffer */ 1686 uint32_t buf1_size; 1687 uint32_t buf2_size; 1688 1689 buf1_size = 1024; 1690 buf2_size = 1024; 1691 1692 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 1693 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 1694 1695 /* Write the Initial ID into the buffer */ 1696 (void) sprintf(buf2, "%s: %08x %08x", LEGEND_CR4_INITIAL_LOAD, 1697 pBuffer->InitialId[0], pBuffer->InitialId[1]); 1698 (void) strcat(buf1, buf2); 1699 1700 /* Write the Flags Word into the buffer */ 1701 (void) sprintf(buf2, "\n %s: %08x", LEGEND_CR4_FLAGS, pBuffer->Flags); 1702 (void) strcat(buf1, buf2); 1703 1704 /* Write the Boot Bios ID into the buffer */ 1705 (void) sprintf(buf2, "\n %s: %08x %08x", LEGEND_CR4_BOOT_BIOS_ID, 1706 pBuffer->BootBiosId[0], pBuffer->BootBiosId[1]); 1707 (void) strcat(buf1, buf2); 1708 1709 /* Write the SLI1 ID into the buffer */ 1710 (void) sprintf(buf2, "\n %s: %08x %08x", LEGEND_CR4_SLI1_ID, 1711 pBuffer->Sli1Id[0], pBuffer->Sli1Id[1]); 1712 (void) strcat(buf1, buf2); 1713 1714 /* Write the SLI2 ID into the buffer */ 1715 (void) sprintf(buf2, "\n %s: %08x %08x", LEGEND_CR4_SLI2_ID, 1716 pBuffer->Sli2Id[0], pBuffer->Sli2Id[1]); 1717 (void) strcat(buf1, buf2); 1718 1719 /* Write the SLI3 ID into the buffer */ 1720 (void) sprintf(buf2, "\n %s: %08x %08x", LEGEND_CR4_SLI3_ID, 1721 pBuffer->Sli3Id[0], pBuffer->Sli3Id[1]); 1722 (void) strcat(buf1, buf2); 1723 1724 /* Write the SLI4 ID into the buffer */ 1725 (void) sprintf(buf2, "\n %s: %08x %08x", LEGEND_CR4_SLI4_ID, 1726 pBuffer->Sli4Id[0], pBuffer->Sli4Id[1]); 1727 (void) strcat(buf1, buf2); 1728 1729 /* Write the Erom ID into the buffer */ 1730 (void) sprintf(buf2, "\n %s: %08x %08x", LEGEND_CR4_EROM_ID, 1731 pBuffer->EromId[0], pBuffer->EromId[1]); 1732 (void) strcat(buf1, buf2); 1733 1734 status = 1735 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION, 1736 LEGEND_CONFIG_REGION_4, 0); 1737 1738 kmem_free(buf1, buf1_size); 1739 kmem_free(buf2, buf2_size); 1740 1741 return (status); 1742 1743 } /* emlxs_dump_cfg_region4_decoded() */ 1744 1745 1746 /* ARGSUSED */ 1747 uint32_t 1748 emlxs_dump_cfg_region14_decoded( 1749 emlxs_hba_t *hba, 1750 emlxs_file_t *fpTxtFile, 1751 char *pLidLegend, 1752 char *pBuffer, 1753 uint32_t ByteCount) 1754 { 1755 uint32_t status; 1756 char *buf1; /* text buffer */ 1757 char *buf2; /* text buffer */ 1758 uint32_t buf1_size; 1759 uint32_t buf2_size; 1760 int i; 1761 uint8_t tag; 1762 uint16_t length; 1763 uint16_t length2; 1764 char mnemonic[4]; 1765 int fDone = FALSE; /* flag to exit VPD loop */ 1766 1767 #ifdef EMLXS_BIG_ENDIAN 1768 uint32_t *wptr; 1769 uint32_t w1; 1770 #endif 1771 1772 buf1_size = 1024; 1773 buf2_size = 1024; 1774 1775 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 1776 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 1777 1778 /* If Big Endian, swap the data in place, */ 1779 /* because it's PCI Data (Little Endian) */ 1780 #ifdef EMLXS_BIG_ENDIAN 1781 wptr = (uint32_t *)pBuffer; 1782 for (i = 0; i < (int)ByteCount / 4; i++, wptr++) { 1783 w1 = *wptr; 1784 *wptr = BE_SWAP32(w1); 1785 } 1786 #endif /* EMLXS_BIG_ENDIAN */ 1787 1788 /* Decode the VPD Data and write it into the buffer */ 1789 1790 /* CR 26941 */ 1791 /* NOTE: The following code is correct, */ 1792 /* should work, and used to work. */ 1793 /* pBuffer points to char, and the symbol VPD_TAG_82 is 0x82. */ 1794 /* The test is an equality test, not a relational test. */ 1795 /* The compiler should generate an 8 bit test, and */ 1796 /* sign extension does not apply. */ 1797 /* I don't know when or why it stopped working, */ 1798 /* and don't have time to dig. */ 1799 /* The cast fixes it. */ 1800 1801 if (((unsigned char)pBuffer[0]) != VPD_TAG_82) { 1802 (void) sprintf(buf1, "Bad VPD Data: (w0=0x%08x)", 1803 *(uint32_t *)pBuffer); 1804 } else { /* begin good data */ 1805 i = 0; 1806 while (!fDone) { 1807 tag = pBuffer[i++]; 1808 length = pBuffer[i++]; 1809 length |= (pBuffer[i++] << 8); 1810 1811 switch (tag) { 1812 case VPD_TAG_82: 1813 (void) strncpy(buf2, &pBuffer[i], 1814 length > buf2_size ? buf2_size : length); 1815 buf2[length > 1816 (buf2_size - 1) ? (buf2_size - 1817 1) : length] = 0; 1818 (void) strcat(buf1, "Name: "); 1819 (void) strcat(buf1, buf2); 1820 i += length; 1821 break; 1822 1823 case VPD_TAG_90: 1824 for (;;) { 1825 mnemonic[0] = pBuffer[i++]; 1826 mnemonic[1] = pBuffer[i++]; 1827 mnemonic[2] = 0; 1828 1829 if (strcmp(mnemonic, "RV") == 0) { 1830 fDone = TRUE; 1831 break; 1832 } 1833 1834 if (mnemonic[0] == 0) { 1835 fDone = TRUE; 1836 break; 1837 } 1838 1839 length2 = pBuffer[i++]; 1840 (void) sprintf(buf2, "\n %s: ", 1841 mnemonic); 1842 (void) strcat(buf1, buf2); 1843 (void) strncpy(buf2, &pBuffer[i], 1844 length2 > 1845 buf2_size ? buf2_size : length2); 1846 buf2[length2 > 1847 (buf2_size - 1) ? (buf2_size - 1848 1) : length2] = 0; 1849 (void) strcat(buf1, buf2); 1850 i += length2; 1851 } 1852 break; 1853 1854 default: 1855 break; 1856 1857 } /* end switch */ 1858 1859 } /* end while */ 1860 1861 } /* good data */ 1862 1863 status = 1864 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION, 1865 LEGEND_CONFIG_REGION_14, 0); 1866 1867 kmem_free(buf1, buf1_size); 1868 kmem_free(buf2, buf2_size); 1869 1870 return (status); 1871 1872 } /* emlxs_dump_cfg_region14_decoded() */ 1873 1874 1875 static uint32_t 1876 emlxs_dump_cfg_region( 1877 emlxs_hba_t *hba, 1878 emlxs_file_t *fpTxtFile, 1879 emlxs_file_t *fpDmpFile, 1880 uint8_t Region, 1881 char *pLidLegend, 1882 int fSwap) 1883 { 1884 uint32_t status; 1885 uint32_t RetByteCount = 0; /* returned byte count */ 1886 char *buf1; /* string ops buffer */ 1887 char *buf2; /* string ops buffer */ 1888 uint32_t buf1_size; 1889 uint32_t buf2_size; 1890 uint32_t *buffer; 1891 int i; 1892 1893 #ifdef EMLXS_LITTLE_ENDIAN 1894 fSwap = FALSE; 1895 #endif /* EMLXS_LITTLE_ENDIAN */ 1896 1897 buf1_size = 4096; 1898 buf2_size = 1024; 1899 1900 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 1901 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 1902 1903 buffer = 1904 (uint32_t *)kmem_zalloc(DUMP_MAX_CONFIG_REGION_LENGTH, KM_SLEEP); 1905 1906 status = 1907 emlxs_read_cfg_region(hba, Region, DUMP_MAX_CONFIG_REGION_LENGTH, 1908 &RetByteCount, (uint8_t *)buffer); 1909 1910 if (status != 0) { 1911 kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH); 1912 kmem_free(buf1, buf1_size); 1913 kmem_free(buf2, buf2_size); 1914 return (status); 1915 } 1916 1917 /* Write the Data into the buffer */ 1918 for (i = 0; i < (int)RetByteCount / 4; i++) { 1919 if ((i % 8 == 0) && (i != 0)) { 1920 (void) strcat((char *)buf1, "\n "); 1921 } 1922 1923 (void) sprintf(buf2, "%08x, ", buffer[i]); 1924 (void) strcat((char *)buf1, buf2); 1925 } 1926 1927 status = 1928 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION, 1929 pLidLegend, 0); 1930 1931 status = emlxs_dump_host_block(fpDmpFile, 1932 (uint8_t *)buffer, 1933 RetByteCount, 1934 SID_CONFIG_REGION, LEGEND_CONFIG_REGION, pLidLegend, fSwap); 1935 1936 if (Region == 4) { 1937 status = 1938 emlxs_dump_cfg_region4_decoded(hba, fpTxtFile, pLidLegend, 1939 (DUMP_WAKE_UP_PARAMS *)buffer, RetByteCount); 1940 } 1941 1942 if (Region == 14) { 1943 status = 1944 emlxs_dump_cfg_region14_decoded(hba, fpTxtFile, 1945 pLidLegend, (char *)buffer, RetByteCount); 1946 } 1947 1948 kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH); 1949 kmem_free(buf1, buf1_size); 1950 kmem_free(buf2, buf2_size); 1951 1952 return (status); 1953 1954 } /* emlxs_dump_cfg_region() */ 1955 1956 1957 static uint32_t 1958 emlxs_dump_cfg_regions( 1959 emlxs_hba_t *hba, 1960 emlxs_file_t *fpTxtFile, 1961 emlxs_file_t *fpDmpFile) 1962 { 1963 uint32_t status; 1964 1965 status = 1966 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 0, 1967 LEGEND_CONFIG_REGION_0, FALSE); 1968 1969 status = 1970 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 1, 1971 LEGEND_CONFIG_REGION_1, FALSE); 1972 1973 status = 1974 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 2, 1975 LEGEND_CONFIG_REGION_2, FALSE); 1976 1977 status = 1978 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 3, 1979 LEGEND_CONFIG_REGION_3, FALSE); 1980 1981 status = 1982 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 4, 1983 LEGEND_CONFIG_REGION_4, FALSE); 1984 1985 status = 1986 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 5, 1987 LEGEND_CONFIG_REGION_5, FALSE); 1988 1989 status = 1990 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 6, 1991 LEGEND_CONFIG_REGION_6, FALSE); 1992 1993 status = 1994 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 7, 1995 LEGEND_CONFIG_REGION_7, FALSE); 1996 1997 status = 1998 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 8, 1999 LEGEND_CONFIG_REGION_8, TRUE); 2000 2001 status = 2002 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 9, 2003 LEGEND_CONFIG_REGION_9, TRUE); 2004 2005 status = 2006 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 10, 2007 LEGEND_CONFIG_REGION_10, TRUE); 2008 2009 status = 2010 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 11, 2011 LEGEND_CONFIG_REGION_11, FALSE); 2012 2013 status = 2014 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 12, 2015 LEGEND_CONFIG_REGION_12, FALSE); 2016 2017 status = 2018 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 13, 2019 LEGEND_CONFIG_REGION_13, FALSE); 2020 2021 status = 2022 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 14, 2023 LEGEND_CONFIG_REGION_14, FALSE); 2024 2025 status = 2026 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 15, 2027 LEGEND_CONFIG_REGION_15, FALSE); 2028 2029 status = 2030 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 16, 2031 LEGEND_CONFIG_REGION_16, FALSE); 2032 2033 status = 2034 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 17, 2035 LEGEND_CONFIG_REGION_17, FALSE); 2036 2037 status = 2038 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 18, 2039 LEGEND_CONFIG_REGION_18, FALSE); 2040 2041 status = 2042 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 19, 2043 LEGEND_CONFIG_REGION_19, FALSE); 2044 2045 status = 2046 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 20, 2047 LEGEND_CONFIG_REGION_20, FALSE); 2048 2049 status = 2050 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 21, 2051 LEGEND_CONFIG_REGION_21, FALSE); 2052 2053 status = 2054 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 22, 2055 LEGEND_CONFIG_REGION_22, FALSE); 2056 2057 status = 2058 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 23, 2059 LEGEND_CONFIG_REGION_23, FALSE); 2060 2061 status = 2062 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 24, 2063 LEGEND_CONFIG_REGION_24, FALSE); 2064 2065 status = 2066 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 25, 2067 LEGEND_CONFIG_REGION_25, FALSE); 2068 2069 status = 2070 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 26, 2071 LEGEND_CONFIG_REGION_26, FALSE); 2072 2073 status = 2074 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 27, 2075 LEGEND_CONFIG_REGION_27, FALSE); 2076 2077 status = 2078 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 28, 2079 LEGEND_CONFIG_REGION_28, FALSE); 2080 2081 status = 2082 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 29, 2083 LEGEND_CONFIG_REGION_29, FALSE); 2084 2085 status = 2086 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 30, 2087 LEGEND_CONFIG_REGION_30, FALSE); 2088 2089 status = 2090 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 31, 2091 LEGEND_CONFIG_REGION_31, FALSE); 2092 2093 status = 2094 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 32, 2095 LEGEND_CONFIG_REGION_32, FALSE); 2096 2097 return (status); 2098 2099 } /* emlxs_dump_cfg_regions() */ 2100 2101 2102 /*ARGSUSED*/ 2103 static uint32_t 2104 emlxs_dump_os_version( 2105 emlxs_hba_t *hba, 2106 emlxs_file_t *fpTxtFile, 2107 emlxs_file_t *fpDmpFile) 2108 { 2109 uint32_t status; 2110 char *buf1; 2111 char *buf2; 2112 uint32_t buf1_size; 2113 uint32_t buf2_size; 2114 2115 buf1_size = 1024; 2116 buf2_size = 1024; 2117 2118 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 2119 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 2120 2121 /* First, write the OS Name string into the buffer */ 2122 (void) strcpy(buf1, utsname.sysname); 2123 2124 /* Second, write the Version Info into the buffer */ 2125 (void) sprintf(buf2, ", %s", utsname.release); 2126 (void) strcat(buf1, buf2); 2127 2128 status = 2129 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO, 2130 LEGEND_REV_OS_VERSION, 0); 2131 2132 status = 2133 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_REV_INFO, 2134 LEGEND_REV_INFO, LEGEND_REV_OS_VERSION); 2135 2136 kmem_free(buf1, buf1_size); 2137 kmem_free(buf2, buf2_size); 2138 2139 return (status); 2140 2141 } /* emlxs_dump_os_version() */ 2142 2143 2144 /*ARGSUSED*/ 2145 static uint32_t 2146 emlxs_dump_drv_version( 2147 emlxs_hba_t *hba, 2148 emlxs_file_t *fpTxtFile, 2149 emlxs_file_t *fpDmpFile) 2150 { 2151 uint32_t status; 2152 char *buf1; 2153 char *buf2; 2154 uint32_t buf1_size; 2155 uint32_t buf2_size; 2156 2157 buf1_size = 1024; 2158 buf2_size = 1024; 2159 2160 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP); 2161 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP); 2162 2163 /* Write the Driver Type into the buffer */ 2164 (void) strcpy(buf1, "Driver Type: "); 2165 (void) strcat(buf1, DUMP_DRV_LEADVILLE); 2166 2167 /* Write the Driver Name into the buffer */ 2168 (void) sprintf(buf2, "%s", DRIVER_NAME); 2169 (void) strcat(buf1, "\n Driver Name: "); 2170 (void) strcat(buf1, buf2); 2171 2172 /* Write the Driver Version into the buffer */ 2173 (void) sprintf(buf2, "%s", emlxs_version); 2174 (void) strcat(buf1, "\n Driver Version: "); 2175 (void) strcat(buf1, buf2); 2176 2177 status = 2178 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO, 2179 LEGEND_REV_DRV_VERSION, 0); 2180 2181 status = 2182 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_REV_INFO, 2183 LEGEND_REV_INFO, LEGEND_REV_DRV_VERSION); 2184 2185 kmem_free(buf1, buf1_size); 2186 kmem_free(buf2, buf2_size); 2187 2188 return (status); 2189 2190 } /* emlxs_dump_drv_version() */ 2191 2192 2193 static uint32_t 2194 emlxs_dump_file_create( 2195 emlxs_hba_t *hba, 2196 emlxs_file_t ** fpTxtFile, 2197 emlxs_file_t ** fpDmpFile, 2198 emlxs_file_t ** fpCeeFile) 2199 { 2200 if (fpTxtFile) { 2201 /* Create the Dump Files */ 2202 if ((*fpTxtFile = emlxs_fopen(hba, EMLXS_TXT_FILE)) == NULL) { 2203 return (1); 2204 } 2205 } 2206 2207 if (fpCeeFile) { 2208 *fpCeeFile = NULL; 2209 2210 if ((hba->model_info.device_id == PCI_DEVICE_ID_LP21000_M) || 2211 (hba->model_info.chip == EMLXS_BE2_CHIP) || 2212 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 2213 if ((*fpCeeFile = 2214 emlxs_fopen(hba, EMLXS_CEE_FILE)) == NULL) { 2215 emlxs_fdelete(*fpTxtFile); 2216 return (1); 2217 } 2218 } 2219 } 2220 2221 if (fpDmpFile) { 2222 if ((*fpDmpFile = emlxs_fopen(hba, EMLXS_DMP_FILE)) == NULL) { 2223 emlxs_fdelete(*fpTxtFile); 2224 emlxs_fdelete(*fpCeeFile); 2225 return (1); 2226 } 2227 2228 /* Initialize the DMP File */ 2229 /* Write the single-byte Dump Identification */ 2230 /* SID to the DMP File */ 2231 #ifdef EMLXS_LITTLE_ENDIAN 2232 emlxs_fputc(SID_DUMP_ID_LE, *fpDmpFile); 2233 #endif /* EMLXS_LITTLE_ENDIAN */ 2234 2235 #ifdef EMLXS_BIG_ENDIAN 2236 emlxs_fputc(SID_DUMP_ID_BE, *fpDmpFile); 2237 #endif /* EMLXS_BIG_ENDIAN */ 2238 2239 emlxs_fputc(SID_NULL, *fpDmpFile); 2240 emlxs_fputc(SID_NULL, *fpDmpFile); 2241 emlxs_fputc(SID_NULL, *fpDmpFile); 2242 emlxs_fflush(*fpDmpFile); 2243 } 2244 2245 return (0); 2246 2247 } /* emlxs_dump_file_create() */ 2248 2249 2250 static uint32_t 2251 emlxs_dump_file_terminate( 2252 emlxs_hba_t *hba, 2253 emlxs_file_t *fpTxtFile, 2254 emlxs_file_t *fpDmpFile, 2255 emlxs_file_t *fpCeeFile) 2256 { 2257 2258 if (fpTxtFile) { 2259 /* Write a suitable string to the Dump TXT File */ 2260 (void) emlxs_fprintf(fpTxtFile, "Dump File End\n"); 2261 emlxs_fflush(fpTxtFile); 2262 } 2263 2264 if (fpCeeFile) { 2265 if (hba->model_info.device_id == PCI_DEVICE_ID_LP21000_M) { 2266 (void) emlxs_fprintf(fpCeeFile, "Dump File End\n"); 2267 } 2268 2269 emlxs_fflush(fpCeeFile); 2270 } 2271 2272 /* Write the single-byte Dump Termination SID to the DMP File */ 2273 if (fpDmpFile) { 2274 emlxs_fputc(SID_DUMP_TERM, fpDmpFile); 2275 emlxs_fflush(fpDmpFile); 2276 } 2277 2278 2279 return (0); 2280 2281 } /* emlxs_dump_file_terminate() */ 2282 2283 2284 static uint32_t 2285 emlxs_dump_file_close( 2286 emlxs_file_t *fpTxtFile, 2287 emlxs_file_t *fpDmpFile, 2288 emlxs_file_t *fpCeeFile) 2289 { 2290 2291 if (fpTxtFile) { 2292 (void) emlxs_fclose(fpTxtFile); 2293 } 2294 2295 if (fpCeeFile) { 2296 (void) emlxs_fclose(fpCeeFile); 2297 } 2298 2299 if (fpDmpFile) { 2300 (void) emlxs_fclose(fpDmpFile); 2301 } 2302 2303 return (0); 2304 2305 } /* emlxs_dump_file_close() */ 2306 2307 2308 /* ************************************************************************* */ 2309 /* ************************************************************************* */ 2310 /* Dump Generators, High Level */ 2311 /* ************************************************************************* */ 2312 /* ************************************************************************* */ 2313 2314 2315 static uint32_t 2316 emlxs_dump_rev_info( 2317 emlxs_hba_t *hba, 2318 emlxs_file_t *fpTxtFile, 2319 emlxs_file_t *fpDmpFile) 2320 { 2321 (void) emlxs_dump_os_version(hba, fpTxtFile, fpDmpFile); 2322 (void) emlxs_dump_drv_version(hba, fpTxtFile, fpDmpFile); 2323 return (0); 2324 2325 } /* emlxs_dump_rev_info() */ 2326 2327 2328 /* ARGSUSED */ 2329 static uint32_t 2330 emlxs_dump_hba_info( 2331 emlxs_hba_t *hba, 2332 emlxs_file_t *fpTxtFile, 2333 emlxs_file_t *fpDmpFile, 2334 uint32_t dump_type) 2335 { 2336 (void) emlxs_dump_model(hba, fpTxtFile, fpDmpFile); 2337 (void) emlxs_dump_wwn(hba, fpTxtFile, fpDmpFile); 2338 (void) emlxs_dump_serial_number(hba, fpTxtFile, fpDmpFile); 2339 (void) emlxs_dump_fw_version(hba, fpTxtFile, fpDmpFile); 2340 (void) emlxs_dump_boot_version(hba, fpTxtFile, fpDmpFile); 2341 2342 2343 return (0); 2344 2345 } /* emlxs_dump_hba_info() */ 2346 2347 2348 /* ************************************************************************* */ 2349 /* emlxs_dump_table_check */ 2350 /* Examine Dump Table, and determine its size. */ 2351 /* Count and include ID SIDs, and the TERM SID, */ 2352 /* but not the Pointer at Addr 654. */ 2353 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */ 2354 /* ************************************************************************* */ 2355 static uint32_t 2356 emlxs_dump_table_check( 2357 emlxs_hba_t *hba, 2358 uint32_t *pSize) 2359 { 2360 emlxs_port_t *port = &PPORT; 2361 int fDone = FALSE; /* loop control flag */ 2362 uint32_t tableSize = 0; /* dump table size (word count) */ 2363 MAILBOX *mb; 2364 MAILBOXQ *mbq; 2365 uint32_t DumpTableAddr; 2366 DUMP_TABLE_ENTRY entry; 2367 2368 *pSize = 0; 2369 2370 /* Read 1 word from low memory at address 654; */ 2371 /* save the returned Dump Table Base Address */ 2372 2373 mbq = 2374 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP); 2375 mb = (MAILBOX *) mbq; 2376 2377 /* Read the dump table address */ 2378 emlxs_mb_dump(hba, mbq, 0x654, 1); 2379 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 2380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2381 "Unable to read dump table address. "\ 2382 "offset=0x654 status=%x", 2383 mb->mbxStatus); 2384 2385 kmem_free(mbq, sizeof (MAILBOXQ)); 2386 return (1); 2387 } 2388 2389 DumpTableAddr = mb->un.varDmp.resp_offset; 2390 2391 if (DumpTableAddr == 0) { 2392 kmem_free(mbq, sizeof (MAILBOXQ)); 2393 return (1); 2394 } 2395 2396 /* Now loop reading Dump Table Entries.. */ 2397 /* break out when we see a Terminator SID */ 2398 while (!fDone) { 2399 emlxs_mb_dump(hba, mbq, DumpTableAddr, 2); 2400 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 2401 MBX_SUCCESS) { 2402 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2403 "Unable to read dump table entry. "\ 2404 "offset=%x status=%x", 2405 DumpTableAddr, mb->mbxStatus); 2406 2407 kmem_free(mbq, sizeof (MAILBOXQ)); 2408 return (1); 2409 } 2410 2411 entry.un.PortBlock.un.w[0] = mb->un.varWords[4]; 2412 2413 switch (entry.un.PortBlock.un.s.sid) { 2414 /* New Dump Table */ 2415 case SID_ID01: 2416 tableSize++; 2417 DumpTableAddr += 4; 2418 break; 2419 2420 #ifdef CC_DUMP_USE_ALL_TABLES 2421 /* New Dump Table */ 2422 case SID_ID02: 2423 case SID_ID03: 2424 tableSize++; 2425 DumpTableAddr += 4; 2426 break; 2427 #else 2428 /* New Dump Table */ 2429 case SID_ID02: 2430 case SID_ID03: 2431 tableSize++; 2432 fDone = TRUE; 2433 break; 2434 #endif /* CC_DUMP_USE_ALL_TABLES */ 2435 2436 /* Dump Table(s) Termination - all done */ 2437 case SID_TERM: 2438 tableSize++; 2439 fDone = TRUE; 2440 break; 2441 2442 /* Dump Table Entry */ 2443 default: 2444 tableSize += 2; 2445 DumpTableAddr += 8; 2446 break; 2447 } 2448 2449 } /* end while */ 2450 2451 *pSize = (tableSize * 4); /* return the total Dump Table size */ 2452 2453 kmem_free(mbq, sizeof (MAILBOXQ)); 2454 return (0); 2455 2456 } /* emlxs_dump_table_check() */ 2457 2458 2459 /* ************************************************************************ */ 2460 /* emlxs_dump_table_read */ 2461 /* Read the Dump Table and store it, for use */ 2462 /* subsequently in emlxs_dump_hba_memory. */ 2463 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */ 2464 /* ************************************************************************ */ 2465 static uint32_t 2466 emlxs_dump_table_read( 2467 emlxs_hba_t *hba, 2468 emlxs_file_t *fpTxtFile, 2469 uint32_t **ppDumpTable, 2470 uint32_t *pDumpTableSize) 2471 { 2472 emlxs_port_t *port = &PPORT; 2473 uint32_t status = 0; 2474 int fDone = FALSE; 2475 MAILBOXQ *mbq; 2476 MAILBOX *mb; 2477 uint32_t *pDumpTableEntry; 2478 uint32_t DumpTableAddr; 2479 DUMP_TABLE_ENTRY entry; 2480 2481 char buf2[256]; 2482 char *buf1; 2483 uint32_t size = (32 * 1024); 2484 2485 /* First, check the dump table and if valid, get its size */ 2486 status = emlxs_dump_table_check(hba, pDumpTableSize); 2487 if (status != 0) { 2488 return (status); 2489 } 2490 2491 buf1 = (char *)kmem_zalloc(size, KM_SLEEP); 2492 2493 /* Allocate a buffer to hold the Dump Table */ 2494 *ppDumpTable = (uint32_t *)kmem_zalloc(*pDumpTableSize, KM_SLEEP); 2495 2496 pDumpTableEntry = *ppDumpTable; 2497 2498 /* Read 1 word from low memory at address 654; */ 2499 /* save the returned Dump Table Base Address */ 2500 mbq = 2501 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP); 2502 2503 mb = (MAILBOX *) mbq; 2504 2505 /* Read the dump table address */ 2506 emlxs_mb_dump(hba, mbq, 0x654, 1); 2507 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 2508 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2509 "Unable to read dump table address. "\ 2510 "offset=0x654 status=%x", 2511 mb->mbxStatus); 2512 2513 kmem_free(buf1, size); 2514 kmem_free(mbq, sizeof (MAILBOXQ)); 2515 2516 kmem_free(*ppDumpTable, *pDumpTableSize); 2517 *pDumpTableSize = 0; 2518 *ppDumpTable = NULL; 2519 2520 return (1); 2521 } 2522 2523 DumpTableAddr = mb->un.varDmp.resp_offset; 2524 2525 if (DumpTableAddr == 0) { 2526 kmem_free(buf1, size); 2527 kmem_free(mbq, sizeof (MAILBOXQ)); 2528 2529 kmem_free(*ppDumpTable, *pDumpTableSize); 2530 *pDumpTableSize = 0; 2531 *ppDumpTable = NULL; 2532 2533 return (1); 2534 } 2535 2536 2537 /* Now loop reading Dump Table Entries.. */ 2538 /* break out when we see a Terminator SID */ 2539 while (!fDone) { 2540 emlxs_mb_dump(hba, mbq, DumpTableAddr, 2); 2541 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 2542 MBX_SUCCESS) { 2543 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2544 "Unable to read dump table entry. "\ 2545 "offset=%x status=%x", 2546 DumpTableAddr, mb->mbxStatus); 2547 2548 kmem_free(buf1, size); 2549 kmem_free(mbq, sizeof (MAILBOXQ)); 2550 2551 kmem_free(*ppDumpTable, *pDumpTableSize); 2552 *pDumpTableSize = 0; 2553 *ppDumpTable = NULL; 2554 2555 return (1); 2556 } 2557 2558 (void) sprintf(buf2, "\n Addr=%08x: ", mb->un.varDmp.base_adr); 2559 (void) strcat(buf1, buf2); 2560 2561 entry.un.PortBlock.un.w[0] = mb->un.varWords[4]; 2562 *pDumpTableEntry++ = mb->un.varWords[4]; 2563 2564 switch (entry.un.PortBlock.un.s.sid) { 2565 /* New Dump Table */ 2566 case SID_ID01: 2567 (void) sprintf(buf2, "w0=%08x", 2568 entry.un.PortBlock.un.w[0]); 2569 (void) strcat(buf1, buf2); 2570 DumpTableAddr += 4; 2571 break; 2572 2573 #ifdef CC_DUMP_USE_ALL_TABLES 2574 /* New Dump Table */ 2575 case SID_ID02: 2576 case SID_ID03: 2577 (void) sprintf(buf2, "w0=%08x", 2578 entry.un.PortBlock.un.w[0]); 2579 (void) strcat(buf1, buf2); 2580 DumpTableAddr += 4; 2581 break; 2582 #else 2583 /* New Dump Table */ 2584 case SID_ID02: 2585 case SID_ID03: 2586 (void) sprintf(buf2, "w0=%08x", 2587 entry.un.PortBlock.un.w[0]); 2588 (void) strcat(buf1, buf2); 2589 fDone = TRUE; 2590 break; 2591 #endif /* CC_DUMP_USE_ALL_TABLES */ 2592 2593 /* Dump Table(s) Termination - all done */ 2594 case SID_TERM: 2595 (void) sprintf(buf2, "w0=%08x", 2596 entry.un.PortBlock.un.w[0]); 2597 (void) strcat(buf1, buf2); 2598 fDone = TRUE; 2599 break; 2600 2601 /* Dump Table Entry */ 2602 default: 2603 entry.un.PortBlock.un.w[1] = mb->un.varWords[5]; 2604 *pDumpTableEntry++ = mb->un.varWords[5]; 2605 2606 (void) sprintf(buf2, "w0=%08x, w1=%08x", 2607 entry.un.PortBlock.un.w[0], 2608 entry.un.PortBlock.un.w[1]); 2609 (void) strcat(buf1, buf2); 2610 DumpTableAddr += 8; 2611 break; 2612 } 2613 2614 } /* end while */ 2615 2616 status = 2617 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_MEM_DUMP, 2618 LEGEND_HBA_MEM_DUMP_TABLE, 0); 2619 2620 kmem_free(buf1, size); 2621 kmem_free(mbq, sizeof (MAILBOXQ)); 2622 2623 if (status != 0) { 2624 kmem_free(*ppDumpTable, *pDumpTableSize); 2625 *pDumpTableSize = 0; 2626 *ppDumpTable = NULL; 2627 2628 return (status); 2629 } 2630 2631 return (0); 2632 2633 } /* emlxs_dump_table_read() */ 2634 2635 2636 /* ************************************************************************* */ 2637 /* emlxs_dump_hba_memory */ 2638 /* Guided by the Dump Table previously read in, */ 2639 /* generate the Port Memory Dump. */ 2640 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */ 2641 /* ************************************************************************* */ 2642 static uint32_t 2643 emlxs_dump_hba_memory( 2644 emlxs_hba_t *hba, 2645 emlxs_file_t *fpDmpFile, 2646 uint32_t *pDumpTable) 2647 { 2648 emlxs_port_t *port = &PPORT; 2649 uint32_t status = 0; 2650 int fDone = FALSE; 2651 DUMP_TABLE_ENTRY entry; 2652 MAILBOXQ *mbq; 2653 MAILBOX *mb; 2654 uint32_t byteCount; 2655 uint32_t byteCountRem; 2656 uint8_t *pBuf; 2657 uint8_t *p1; 2658 uint32_t portAddr; 2659 int fSwap = FALSE; 2660 uint32_t offset; 2661 uint32_t wcount; 2662 uint32_t total = 0; 2663 2664 #ifdef EMLXS_BIG_ENDIAN 2665 fSwap = TRUE; 2666 #endif /* EMLXS_BIG_ENDIAN */ 2667 2668 if (!fpDmpFile) { 2669 return (1); 2670 } 2671 2672 mbq = 2673 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP); 2674 2675 mb = (MAILBOX *) mbq; 2676 2677 /* loop reading Dump Table Entries.. break out when */ 2678 /* we see a Terminator SID */ 2679 while (!fDone) { 2680 entry.un.PortBlock.un.w[0] = *pDumpTable++; 2681 2682 switch (entry.un.PortBlock.un.s.sid) { 2683 2684 /* New Dump Table */ 2685 case SID_ID01: 2686 break; 2687 2688 #ifdef CC_DUMP_USE_ALL_TABLES 2689 /* New Dump Table */ 2690 case SID_ID02: 2691 case SID_ID03: 2692 break; 2693 #else 2694 /* New Dump Table */ 2695 case SID_ID02: 2696 case SID_ID03: 2697 fDone = TRUE; 2698 break; 2699 #endif /* CC_DUMP_USE_ALL_TABLES */ 2700 2701 /* Dump Table(s) Termination - all done */ 2702 case SID_TERM: 2703 fDone = TRUE; 2704 break; 2705 2706 default: 2707 /* Dump Table Entry */ 2708 entry.un.PortBlock.un.w[1] = *pDumpTable++; 2709 2710 #ifdef CC_DUMP_FW_BUG_1 2711 if (entry.un.PortBlock.un.w[1] == 0x3E0000) { 2712 break; 2713 } 2714 #endif /* CC_DUMP_FW_BUG_1 */ 2715 2716 /* Check if indirect address, and */ 2717 /* obtain the new address if so */ 2718 if ((entry.un.PortBlock.un.s.addr & 0x80000000) != 0) { 2719 offset = 2720 (entry.un.PortBlock.un.s. 2721 addr & 0x01FFFFFF); 2722 emlxs_mb_dump(hba, mbq, offset, 1); 2723 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 2724 0) != MBX_SUCCESS) { 2725 EMLXS_MSGF(EMLXS_CONTEXT, 2726 &emlxs_init_debug_msg, 2727 "Unable to read dump table entry. "\ 2728 "offset=%x status=%x", 2729 offset, mb->mbxStatus); 2730 2731 kmem_free(mbq, sizeof (MAILBOXQ)); 2732 return (1); 2733 } 2734 2735 /* replace the indirect address in the */ 2736 /* Dump Table */ 2737 entry.un.PortBlock.un.s.addr = 2738 mb->un.varWords[4]; 2739 } 2740 2741 /* determine byte count to dump */ 2742 byteCount = entry.un.PortBlock.un.s.bc; 2743 if (entry.un.PortBlock.un.s.sid & SID_MULT_ELEM) { 2744 if (entry.un.PortStruct.un.s.count == 0) { 2745 byteCount = 2746 256 * 2747 entry.un.PortStruct.un.s.length; 2748 } else { 2749 byteCount = 2750 entry.un.PortStruct.un.s.count * 2751 entry.un.PortStruct.un.s.length; 2752 } 2753 } 2754 2755 total += byteCount; 2756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 2757 "Dump: addr=%x count=%d total=%d", offset, 2758 byteCount, total); 2759 2760 /* allocate a buffer to receive the dump data */ 2761 pBuf = (uint8_t *)kmem_zalloc(byteCount, KM_SLEEP); 2762 2763 /* loop issuing MBX commands, 18x measly words at */ 2764 /* a time */ 2765 2766 /* init vars */ 2767 byteCountRem = byteCount; 2768 p1 = pBuf; 2769 portAddr = entry.un.PortBlock.un.s.addr; 2770 2771 for (;;) { 2772 if (byteCountRem == 0) { 2773 break; 2774 } 2775 2776 wcount = 2777 (byteCountRem / 4 >= 2778 0x18) ? 0x18 : (byteCountRem / 4); 2779 emlxs_mb_dump(hba, mbq, portAddr, wcount); 2780 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 2781 0) != MBX_SUCCESS) { 2782 EMLXS_MSGF(EMLXS_CONTEXT, 2783 &emlxs_init_debug_msg, 2784 "Unable to read dump table entry."\ 2785 " offset=%x wc=%d status=%x", 2786 portAddr, wcount, mb->mbxStatus); 2787 break; 2788 } 2789 2790 bcopy((uint8_t *)&mb->un.varWords[4], p1, 2791 (mb->un.varDmp.word_cnt * 4)); 2792 2793 byteCountRem -= (mb->un.varDmp.word_cnt * 4); 2794 p1 += (mb->un.varDmp.word_cnt * 4); 2795 portAddr += (mb->un.varDmp.word_cnt * 4); 2796 2797 } /* end for */ 2798 2799 if (status == 0) { 2800 if (entry.un.PortBlock.un.s. 2801 sid & SID_MULT_ELEM) { 2802 status = 2803 emlxs_dump_port_struct(fpDmpFile, 2804 pBuf, byteCount, entry, fSwap); 2805 } else { 2806 status = 2807 emlxs_dump_port_block(fpDmpFile, 2808 pBuf, byteCount, entry, fSwap); 2809 } 2810 } 2811 2812 if (pBuf) { 2813 kmem_free(pBuf, byteCount); 2814 } 2815 2816 break; 2817 2818 } /* end switch */ 2819 2820 } /* end while */ 2821 2822 kmem_free(mbq, sizeof (MAILBOXQ)); 2823 2824 return (status); 2825 2826 } /* emlxs_dump_hba_memory() */ 2827 2828 2829 static uint32_t 2830 emlxs_dump_hba( 2831 emlxs_hba_t *hba, 2832 emlxs_file_t *fpTxtFile, 2833 emlxs_file_t *fpDmpFile) 2834 { 2835 uint32_t status = 0; 2836 uint32_t *pDumpTable = 0; 2837 uint32_t DumpTableSize = 0; 2838 2839 if (hba->sli_mode >= EMLXS_HBA_SLI4_MODE) { 2840 return (1); 2841 } 2842 2843 /* HBA should be in WARM state here */ 2844 status = 2845 emlxs_dump_table_read(hba, fpTxtFile, &pDumpTable, 2846 &DumpTableSize); 2847 if (status) { 2848 return (status); 2849 } 2850 2851 status = emlxs_dump_hba_memory(hba, fpDmpFile, pDumpTable); 2852 2853 if (pDumpTable != 0) { 2854 kmem_free(pDumpTable, DumpTableSize); 2855 } 2856 2857 return (status); 2858 2859 } /* emlxs_dump_hba() */ 2860 2861 2862 /* ************************************************************************* */ 2863 /* emlxs_dump_drv_region */ 2864 /* Common subroutine for all the Dump_Sli"Structures" Routines */ 2865 /* NOTE: This routine does not free pBuf. This is by design. */ 2866 /* The caller does it. */ 2867 /* ************************************************************************* */ 2868 static uint32_t 2869 emlxs_dump_drv_region( 2870 emlxs_hba_t *hba, 2871 uint32_t regionId, 2872 uint8_t **pBuf, 2873 uint32_t *pBufLen) 2874 { /* ptr to length of buffer */ 2875 uint32_t status; 2876 uint32_t size; 2877 2878 *pBuf = NULL; 2879 *pBufLen = 0; 2880 2881 size = 0; 2882 status = emlxs_get_dump_region(hba, regionId, NULL, &size); 2883 2884 if (status != 0) { 2885 return (1); 2886 } 2887 2888 /* Now that we know the required length, request the actual data */ 2889 *pBuf = (uint8_t *)kmem_zalloc(size, KM_SLEEP); 2890 2891 status = emlxs_get_dump_region(hba, regionId, *pBuf, &size); 2892 2893 if (status != 0) { 2894 kmem_free(*pBuf, size); 2895 *pBuf = NULL; 2896 2897 return (1); 2898 } 2899 2900 *pBufLen = size; 2901 2902 return (status); 2903 2904 } /* emlxs_dump_drv_region() */ 2905 2906 2907 static uint32_t 2908 emlxs_dump_sli_regs( 2909 emlxs_hba_t *hba, 2910 emlxs_file_t *fpDmpFile) 2911 { 2912 uint32_t status; 2913 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 2914 uint32_t bufLen = 0; /* length of buffer */ 2915 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 2916 2917 #ifdef EMLXS_BIG_ENDIAN 2918 fSwap = TRUE; 2919 #endif /* EMLXS_BIG_ENDIAN */ 2920 2921 if (!fpDmpFile) { 2922 return (1); 2923 } 2924 2925 status = emlxs_dump_drv_region(hba, DR_SLI_REGS, &pBuf, &bufLen); 2926 2927 if (status != 0) { 2928 return (status); 2929 } 2930 2931 status = 2932 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLI_REGS, 2933 LEGEND_SLI_STRUCTURES, LEGEND_SLI_REGS, fSwap); 2934 2935 kmem_free(pBuf, bufLen); 2936 2937 return (status); 2938 2939 } /* emlxs_dump_sli_regs() */ 2940 2941 2942 static uint32_t 2943 emlxs_dump_slim( 2944 emlxs_hba_t *hba, 2945 emlxs_file_t *fpTxtFile, 2946 emlxs_file_t *fpDmpFile, 2947 uint32_t dump_type) 2948 { 2949 uint32_t status; 2950 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 2951 uint32_t bufLen = 0; /* length of buffer */ 2952 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 2953 2954 #ifdef EMLXS_BIG_ENDIAN 2955 fSwap = TRUE; 2956 #endif /* EMLXS_BIG_ENDIAN */ 2957 2958 status = emlxs_dump_drv_region(hba, DR_SLIM, &pBuf, &bufLen); 2959 2960 if (status != 0) { 2961 return (status); 2962 } 2963 2964 /* The SLIM Dump is only useful if it's a */ 2965 /* Driver-Initiated dump, say, after a HW Error */ 2966 if (dump_type == DUMP_TYPE_DRIVER) { 2967 status = 2968 emlxs_dump_word_txtfile(fpTxtFile, (uint32_t *)pBuf, 2969 0x40, LEGEND_SLI_STRUCTURES, LEGEND_SLIM); 2970 } 2971 2972 status = 2973 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLIM, 2974 LEGEND_SLI_STRUCTURES, LEGEND_SLIM, fSwap); 2975 2976 kmem_free(pBuf, bufLen); 2977 2978 return (status); 2979 2980 } /* emlxs_dump_slim() */ 2981 2982 2983 static uint32_t 2984 emlxs_dump_pcb( 2985 emlxs_hba_t *hba, 2986 emlxs_file_t *fpDmpFile) 2987 { 2988 uint32_t status; 2989 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 2990 uint32_t bufLen = 0; /* length of buffer */ 2991 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 2992 2993 #ifdef EMLXS_BIG_ENDIAN 2994 fSwap = TRUE; 2995 #endif /* EMLXS_BIG_ENDIAN */ 2996 2997 if (!fpDmpFile) { 2998 return (1); 2999 } 3000 3001 status = emlxs_dump_drv_region(hba, DR_PCB, &pBuf, &bufLen); 3002 if (status != 0) { 3003 return (status); 3004 } 3005 3006 status = 3007 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PCB, 3008 LEGEND_SLI_STRUCTURES, LEGEND_PCB, fSwap); 3009 3010 kmem_free(pBuf, bufLen); 3011 3012 return (status); 3013 3014 } /* emlxs_dump_pcb() */ 3015 3016 3017 static uint32_t 3018 emlxs_dump_mbox( 3019 emlxs_hba_t *hba, 3020 emlxs_file_t *fpDmpFile) 3021 { 3022 uint32_t status; 3023 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 3024 uint32_t bufLen = 0; /* length of buffer */ 3025 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 3026 3027 #ifdef EMLXS_BIG_ENDIAN 3028 fSwap = TRUE; 3029 #endif /* EMLXS_BIG_ENDIAN */ 3030 3031 if (!fpDmpFile) { 3032 return (1); 3033 } 3034 3035 status = emlxs_dump_drv_region(hba, DR_MBX, &pBuf, &bufLen); 3036 if (status != 0) { 3037 return (status); 3038 } 3039 3040 status = 3041 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_MBX, 3042 LEGEND_SLI_STRUCTURES, LEGEND_MBX, fSwap); 3043 3044 kmem_free(pBuf, bufLen); 3045 3046 return (status); 3047 3048 } /* emlxs_dump_mbox() */ 3049 3050 3051 static uint32_t 3052 emlxs_dump_host_pointers( 3053 emlxs_hba_t *hba, 3054 emlxs_file_t *fpDmpFile) 3055 { 3056 uint32_t status; 3057 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 3058 uint32_t bufLen = 0; /* length of buffer */ 3059 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 3060 3061 #ifdef EMLXS_BIG_ENDIAN 3062 fSwap = TRUE; 3063 #endif /* EMLXS_BIG_ENDIAN */ 3064 3065 if (!fpDmpFile) { 3066 return (1); 3067 } 3068 3069 status = emlxs_dump_drv_region(hba, DR_HOST_PTRS, &pBuf, &bufLen); 3070 if (status != 0) { 3071 return (status); 3072 } 3073 3074 status = 3075 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_HOST_PTRS, 3076 LEGEND_SLI_STRUCTURES, LEGEND_HOST_PTRS, fSwap); 3077 3078 kmem_free(pBuf, bufLen); 3079 3080 return (status); 3081 3082 } /* emlxs_dump_host_pointers() */ 3083 3084 3085 static uint32_t 3086 emlxs_dump_port_pointers( 3087 emlxs_hba_t *hba, 3088 emlxs_file_t *fpDmpFile) 3089 { 3090 uint32_t status; 3091 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 3092 uint32_t bufLen = 0; /* length of buffer */ 3093 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 3094 3095 #ifdef EMLXS_BIG_ENDIAN 3096 fSwap = TRUE; 3097 #endif /* EMLXS_BIG_ENDIAN */ 3098 3099 if (!fpDmpFile) { 3100 return (1); 3101 } 3102 3103 status = emlxs_dump_drv_region(hba, DR_PORT_PTRS, &pBuf, &bufLen); 3104 if (status != 0) { 3105 return (status); 3106 } 3107 3108 status = 3109 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PORT_PTRS, 3110 LEGEND_SLI_STRUCTURES, LEGEND_PORT_PTRS, fSwap); 3111 3112 kmem_free(pBuf, bufLen); 3113 3114 return (status); 3115 3116 } /* emlxs_dump_port_pointers() */ 3117 3118 3119 static uint32_t 3120 emlxs_dump_rings( 3121 emlxs_hba_t *hba, 3122 emlxs_file_t *fpDmpFile) 3123 { 3124 uint32_t status; 3125 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 3126 uint32_t bufLen = 0; /* length of buffer */ 3127 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 3128 3129 #ifdef EMLXS_BIG_ENDIAN 3130 fSwap = TRUE; 3131 #endif /* EMLXS_BIG_ENDIAN */ 3132 3133 if (!fpDmpFile) { 3134 return (1); 3135 } 3136 3137 status = emlxs_dump_drv_region(hba, DR_RINGS, &pBuf, &bufLen); 3138 if (status != 0) { 3139 return (status); 3140 } 3141 3142 status = 3143 emlxs_dump_host_struct(fpDmpFile, pBuf, bufLen, sizeof (IOCB), 3144 bufLen / sizeof (IOCB), SID_RINGS, LEGEND_SLI_STRUCTURES, 3145 LEGEND_RINGS, fSwap); 3146 3147 kmem_free(pBuf, bufLen); 3148 3149 return (status); 3150 3151 } /* emlxs_dump_rings() */ 3152 3153 3154 static uint32_t 3155 emlxs_dump_drv_internals( 3156 emlxs_hba_t *hba, 3157 emlxs_file_t *fpDmpFile) 3158 { 3159 uint32_t status; 3160 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */ 3161 uint32_t bufLen = 0; /* length of buffer */ 3162 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */ 3163 3164 #ifdef EMLXS_BIG_ENDIAN 3165 fSwap = TRUE; 3166 #endif /* EMLXS_BIG_ENDIAN */ 3167 3168 if (!fpDmpFile) { 3169 return (1); 3170 } 3171 3172 status = emlxs_dump_drv_region(hba, DR_INTERNAL, &pBuf, &bufLen); 3173 if (status != 0) { 3174 return (status); 3175 } 3176 3177 status = 3178 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_INTERNAL_SOL, 3179 LEGEND_SLI_STRUCTURES, LEGEND_DRIVER_SPEC, fSwap); 3180 3181 kmem_free(pBuf, bufLen); 3182 3183 return (status); 3184 3185 } /* emlxs_dump_drv_internals() */ 3186 3187 3188 static uint32_t 3189 emlxs_dump_sli_interface( 3190 emlxs_hba_t *hba, 3191 emlxs_file_t *fpTxtFile, 3192 emlxs_file_t *fpDmpFile, 3193 uint32_t dump_type) 3194 { 3195 3196 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) { 3197 /* HBA should be in OFFLINE state here */ 3198 3199 (void) emlxs_dump_sli_regs(hba, fpDmpFile); 3200 (void) emlxs_dump_slim(hba, fpTxtFile, fpDmpFile, dump_type); 3201 (void) emlxs_dump_pcb(hba, fpDmpFile); 3202 (void) emlxs_dump_mbox(hba, fpDmpFile); 3203 (void) emlxs_dump_host_pointers(hba, fpDmpFile); 3204 (void) emlxs_dump_port_pointers(hba, fpDmpFile); 3205 (void) emlxs_dump_rings(hba, fpDmpFile); 3206 } 3207 3208 (void) emlxs_dump_drv_internals(hba, fpDmpFile); 3209 3210 return (0); 3211 3212 } /* emlxs_dump_sli_interface() */ 3213 3214 3215 static uint32_t 3216 emlxs_dump_menlo_log( 3217 emlxs_hba_t *hba, 3218 emlxs_file_t *fpCeeFile) 3219 { 3220 uint32_t RmStatus; 3221 int i, j; 3222 int isWrapped = FALSE; 3223 char buf1[2048] = { 0 }; 3224 char buf2[2048] = { 0 }; 3225 3226 /* Get Config Command vars */ 3227 menlo_get_config_rsp_t GcBuf; 3228 menlo_get_config_rsp_t *pGcBuf = &GcBuf; 3229 3230 /* Get Log Config Command vars */ 3231 uint32_t LcBufSize; 3232 menlo_rsp_t *pLcBuf = NULL; 3233 uint32_t NumLogs; 3234 menlo_log_t *pLcEntry; 3235 3236 /* Get Log Data Command vars */ 3237 uint32_t LdBufSize; 3238 menlo_rsp_t *pLdBuf = NULL; 3239 uint16_t Head; 3240 uint8_t *pLogEntry; 3241 char *pLogString; 3242 3243 /* Get Panic Log Command vars */ 3244 uint32_t PlBufSize; 3245 menlo_rsp_t *pPlBuf = NULL; 3246 uint32_t PanicLogEntryCount; 3247 uint32_t PanicLogEntrySize; 3248 3249 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 3250 return (DFC_INVALID_ADAPTER); 3251 } 3252 3253 /* First, issue a GetConfig command, which gives us */ 3254 /* the Log Config and Panic Log sizes */ 3255 3256 RmStatus = 3257 emlxs_menlo_get_cfg(hba, pGcBuf, sizeof (menlo_get_config_rsp_t)); 3258 3259 if (RmStatus != 0) { 3260 goto done; 3261 } 3262 3263 LcBufSize = GcBuf.log_cfg_size + 8; 3264 PlBufSize = GcBuf.panic_log_size; 3265 3266 pLcBuf = (menlo_rsp_t *)kmem_zalloc(LcBufSize, KM_SLEEP); 3267 3268 RmStatus = emlxs_menlo_get_logcfg(hba, pLcBuf, LcBufSize); 3269 3270 if (RmStatus != 0) { 3271 goto done; 3272 } 3273 3274 buf1[0] = 0; 3275 RmStatus = 3276 emlxs_dump_string_txtfile(fpCeeFile, buf1, 3277 LEGEND_MENLO_LOG_CONFIG, LEGEND_NULL, 0); 3278 3279 NumLogs = pLcBuf->log_cfg.num_logs; 3280 pLcEntry = (menlo_log_t *)&pLcBuf->log_cfg.data; 3281 3282 buf1[0] = 0; 3283 (void) sprintf(buf2, "LogId Entries Size Name"); 3284 (void) strcat(buf1, buf2); 3285 (void) sprintf(buf2, "\n----- ------- ---- ----"); 3286 (void) strcat(buf1, buf2); 3287 3288 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3289 3290 for (i = 0; i < (int)NumLogs; i++) { 3291 buf1[0] = 0; 3292 (void) sprintf(buf2, "\n %2d %4d %4d %s", 3293 pLcEntry[i].id, 3294 pLcEntry[i].num_entries, 3295 pLcEntry[i].entry_size, pLcEntry[i].name); 3296 (void) strcat(buf1, buf2); 3297 RmStatus = 3298 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3299 } 3300 3301 /* Now issue a series of GetLogData commands, */ 3302 /* which gives us the actual Logs */ 3303 3304 for (i = 0; i < (int)NumLogs; i++) { 3305 LdBufSize = 3306 (pLcEntry[i].num_entries *pLcEntry[i].entry_size) + 8; 3307 3308 pLdBuf = (menlo_rsp_t *)kmem_zalloc(LdBufSize, KM_SLEEP); 3309 3310 RmStatus = emlxs_menlo_get_log(hba, i, pLdBuf, LdBufSize); 3311 3312 if (RmStatus != 0) { 3313 goto done; 3314 } 3315 3316 /* print a caption for the current log */ 3317 buf1[0] = 0; 3318 (void) sprintf(buf2, "\n\nLog %d:", i); 3319 (void) strcat(buf1, buf2); 3320 (void) sprintf(buf2, " %s", pLcEntry[i].name); 3321 (void) strcat(buf1, buf2); 3322 (void) sprintf(buf2, "\n"); 3323 3324 for (j = 0; j < 75; j++) { 3325 (void) strcat(buf2, "-"); 3326 } 3327 3328 (void) strcat(buf1, buf2); 3329 RmStatus = 3330 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3331 3332 /* check the head entry to determine whether */ 3333 /* the log has wrapped or not */ 3334 Head = pLdBuf->log.head; 3335 pLogEntry = (uint8_t *)&pLdBuf->log.data; 3336 pLogString = 3337 (char *)&(pLogEntry[Head *pLcEntry[i].entry_size]); 3338 3339 isWrapped = FALSE; 3340 if (strlen(pLogString) != 0) { 3341 isWrapped = TRUE; 3342 } 3343 3344 /* if log is wrapped, get entries from the */ 3345 /* Head through the End */ 3346 if (isWrapped) { 3347 for (j = Head; j < (int)pLcEntry[i].num_entries; j++) { 3348 pLogString = 3349 (char *)&(pLogEntry[j * 3350 pLcEntry[i].entry_size]); 3351 buf1[0] = 0; 3352 (void) sprintf(buf2, "\n%3d: %s", j, 3353 pLogString); 3354 (void) strcat(buf1, buf2); 3355 RmStatus = 3356 emlxs_dump_string_txtfile(fpCeeFile, buf1, 3357 0, 0, 1); 3358 } 3359 } 3360 3361 /* if wrapped or not, get entries from the Top */ 3362 /* through the Head */ 3363 for (j = 0; j < Head; j++) { 3364 pLogString = 3365 (char *)&(pLogEntry[j * pLcEntry[i].entry_size]); 3366 buf1[0] = 0; 3367 (void) sprintf(buf2, "\n%3d: %s", j, pLogString); 3368 (void) strcat(buf1, buf2); 3369 RmStatus = 3370 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 3371 1); 3372 } 3373 } /* end for i */ 3374 3375 /* Now issue a GetPanicLog command, which gives us the Panic Log */ 3376 3377 /* print a caption for the current log */ 3378 (void) strcpy(buf1, LEGEND_MENLO_LOG_PANIC_REGS); 3379 buf2[0] = 0; 3380 for (j = 0; j < 75; j++) { 3381 (void) strcat(buf2, "-"); 3382 } 3383 (void) strcat(buf1, buf2); 3384 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3385 3386 pPlBuf = (menlo_rsp_t *)kmem_zalloc(PlBufSize, KM_SLEEP); 3387 3388 RmStatus = emlxs_menlo_get_paniclog(hba, pPlBuf, PlBufSize); 3389 3390 if (RmStatus == 0) { 3391 buf1[0] = 0; 3392 (void) sprintf(buf2, "\nType = %x", 3393 pPlBuf->panic_log.type); 3394 (void) strcat(buf1, buf2); 3395 (void) sprintf(buf2, "\nRegsEpc = %08x", 3396 pPlBuf->panic_log.regs_epc); 3397 (void) strcat(buf1, buf2); 3398 (void) sprintf(buf2, "\nRegsCp0Cause = %08x", 3399 pPlBuf->panic_log.regs_cp0_cause); 3400 (void) strcat(buf1, buf2); 3401 (void) sprintf(buf2, "\nRegsCp0Stat = %08x", 3402 pPlBuf->panic_log.regs_cp0_status); 3403 (void) strcat(buf1, buf2); 3404 RmStatus = 3405 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3406 3407 buf1[0] = 0; 3408 for (i = 0; i < MENLO_NUM_GP_REGS; i++) { 3409 (void) sprintf(buf2, "\nRegsGp[%02x] = %08x", i, 3410 pPlBuf->panic_log.regs_gp[i]); 3411 (void) strcat(buf1, buf2); 3412 } 3413 RmStatus = 3414 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3415 3416 buf1[0] = 0; 3417 (void) sprintf(buf2, "\nLogPresent = %08x", 3418 pPlBuf->panic_log.log_present); 3419 (void) strcat(buf1, buf2); 3420 PanicLogEntryCount = pPlBuf->panic_log.num_entries; 3421 (void) sprintf(buf2, "\nNumEntries = %08x", 3422 PanicLogEntryCount); 3423 (void) strcat(buf1, buf2); 3424 PanicLogEntrySize = pPlBuf->panic_log.entry_size; 3425 (void) sprintf(buf2, "\nEntrySize = %d.", 3426 PanicLogEntrySize); 3427 (void) strcat(buf1, buf2); 3428 (void) sprintf(buf2, "\nHead Entry = %d.", 3429 pPlBuf->panic_log.head); 3430 (void) strcat(buf1, buf2); 3431 RmStatus = 3432 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3433 3434 /* print a caption for the current log */ 3435 (void) strcpy(buf1, LEGEND_MENLO_LOG_PANIC_LOGS); 3436 buf2[0] = 0; 3437 for (j = 0; j < 75; j++) { 3438 (void) strcat(buf2, "-"); 3439 } 3440 (void) strcat(buf1, buf2); 3441 RmStatus = 3442 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1); 3443 3444 /* check the head entry to determine whether the */ 3445 /* log has wrapped or not */ 3446 Head = pPlBuf->panic_log.head; 3447 pLogEntry = (uint8_t *)&pPlBuf->panic_log.data; 3448 pLogString = (char *)&(pLogEntry[Head * PanicLogEntrySize]); 3449 isWrapped = FALSE; 3450 if (strlen(pLogString) != 0) { 3451 isWrapped = TRUE; 3452 } 3453 3454 /* if log is wrapped, get entries from the */ 3455 /* Head through the End */ 3456 if (isWrapped) { 3457 for (j = Head; j < (int)PanicLogEntryCount; j++) { 3458 pLogString = 3459 (char *)&(pLogEntry[j * 3460 PanicLogEntrySize]); 3461 buf1[0] = 0; 3462 (void) sprintf(buf2, "\n%3d: %s", j, 3463 pLogString); 3464 (void) strcat(buf1, buf2); 3465 RmStatus = 3466 emlxs_dump_string_txtfile(fpCeeFile, buf1, 3467 0, 0, 1); 3468 } 3469 } 3470 /* if wrapped or not, get entries from the Top */ 3471 /* through the Head */ 3472 for (j = 0; j < Head; j++) { 3473 pLogString = 3474 (char *)&(pLogEntry[j * PanicLogEntrySize]); 3475 buf1[0] = 0; 3476 (void) sprintf(buf2, "\n%3d: %s", j, pLogString); 3477 (void) strcat(buf1, buf2); 3478 RmStatus = 3479 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 3480 1); 3481 } 3482 } 3483 3484 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, "\n\n", 0, 0, 1); 3485 3486 done: 3487 3488 if (pLdBuf != 0) { 3489 kmem_free(pLdBuf, LdBufSize); 3490 } 3491 3492 if (pLcBuf != 0) { 3493 kmem_free(pLcBuf, LcBufSize); 3494 } 3495 3496 if (pPlBuf != 0) { 3497 kmem_free(pPlBuf, PlBufSize); 3498 } 3499 3500 return (RmStatus); 3501 3502 } /* emlxs_dump_menlo_log() */ 3503 3504 3505 static uint32_t 3506 emlxs_dump_saturn_log( 3507 emlxs_hba_t *hba, 3508 emlxs_file_t *fpTxtFile, 3509 emlxs_file_t *fpDmpFile) 3510 { 3511 emlxs_port_t *port = &PPORT; 3512 MAILBOXQ *mbq; 3513 MAILBOX *mb; 3514 MATCHMAP *mp = NULL; 3515 uint32_t status; 3516 uint32_t logSize = 0; 3517 uintptr_t tempAddress; 3518 int fSwap = FALSE; 3519 uint32_t i; 3520 uint32_t block_size; 3521 uint32_t offset; 3522 3523 #ifdef EMLXS_BIG_ENDIAN 3524 fSwap = TRUE; 3525 #endif /* EMLXS_BIG_ENDIAN */ 3526 3527 if (hba->model_info.chip != EMLXS_SATURN_CHIP) { 3528 return (1); 3529 } 3530 3531 mbq = 3532 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP); 3533 3534 mb = (MAILBOX *) mbq; 3535 3536 /* Step 1: Call MBX_READ_EVENT_LOG_STATUS to get the log size. */ 3537 for (i = 0; i < 10; i++) { 3538 bzero((void *)mb, MAILBOX_CMD_BSIZE); 3539 mb->mbxCommand = MBX_READ_EVENT_LOG_STATUS; 3540 mbq->mbox_cmpl = NULL; 3541 3542 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) == 3543 MBX_SUCCESS) { 3544 break; 3545 } 3546 3547 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3548 "Unable to read event log status. status=%x", 3549 mb->mbxStatus); 3550 3551 if ((mb->mbxStatus & 0xFFFF) == MBXERR_NOT_SUPPORTED || 3552 (mb->mbxStatus & 0xFFFF) == MBX_DRVR_ERROR) { 3553 (void) emlxs_dump_string_txtfile(fpTxtFile, 3554 NV_LOG_NOT_INCLUDED_IN_DMP, 3555 LEGEND_NON_VOLATILE_LOG, 3556 LEGEND_NV_LOG_DRIVER_NOT_SUPPORTED, 0); 3557 3558 kmem_free(mbq, sizeof (MAILBOXQ)); 3559 return (1); 3560 } 3561 3562 /* The call to get the log size simply fails. */ 3563 /* Retry up to 10 times. */ 3564 if ((mb->mbxStatus & 0xFFFF) != MBX_BUSY) { 3565 /* Mailbox fails for some unknown reason. */ 3566 /* Put something in the txt to indicate this case. */ 3567 (void) emlxs_dump_string_txtfile(fpTxtFile, 3568 NV_LOG_NOT_INCLUDED_IN_DMP, 3569 LEGEND_NON_VOLATILE_LOG, 3570 LEGEND_NV_LOG_STATUS_ERROR, 0); 3571 3572 kmem_free(mbq, sizeof (MAILBOXQ)); 3573 return (1); 3574 } 3575 } 3576 3577 if (i >= 10) { 3578 (void) emlxs_dump_string_txtfile(fpTxtFile, 3579 NV_LOG_NOT_INCLUDED_IN_DMP, LEGEND_NON_VOLATILE_LOG, 3580 LEGEND_NV_LOG_STATUS_ERROR, 0); 3581 3582 kmem_free(mbq, sizeof (MAILBOXQ)); 3583 return (1); 3584 } 3585 3586 /* Step 2: Use the log size from step 1 to call MBX_READ_EVENT_LOG */ 3587 logSize = mb->un.varLogStat.size; 3588 3589 if ((mp = emlxs_mem_buf_alloc(hba, logSize)) == 0) { 3590 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3591 "Unable to allocate receive buffer. " 3592 "size=%d", 3593 logSize); 3594 3595 kmem_free(mbq, sizeof (MAILBOXQ)); 3596 return (1); 3597 } 3598 3599 for (offset = 0; offset < logSize; offset = offset + 1024) { 3600 if (logSize - offset < 1024) { 3601 block_size = logSize - offset; 3602 } else { 3603 block_size = 1024; 3604 } 3605 3606 tempAddress = (uintptr_t)(mp->phys + offset); 3607 3608 bzero((void *)mb, MAILBOX_CMD_BSIZE); 3609 mb->mbxCommand = MBX_READ_EVENT_LOG; /* 0x38 */ 3610 mb->un.varRdEvtLog.read_log = 1; /* read log */ 3611 mb->un.varRdEvtLog.mbox_rsp = 0; /* not using Mailbox */ 3612 mb->un.varRdEvtLog.offset = offset; 3613 mb->un.varRdEvtLog.un.sp64.tus.f.bdeFlags = 0x0; 3614 mb->un.varRdEvtLog.un.sp64.tus.f.bdeSize = block_size; 3615 mb->un.varRdEvtLog.un.sp64.addrLow = PADDR_LO(tempAddress); 3616 mb->un.varRdEvtLog.un.sp64.addrHigh = PADDR_HI(tempAddress); 3617 mbq->mbox_cmpl = NULL; 3618 3619 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 3620 MBX_SUCCESS) { 3621 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 3622 "Unable to read event log. status=%x", 3623 mb->mbxStatus); 3624 3625 emlxs_mem_buf_free(hba, mp); 3626 kmem_free(mbq, sizeof (MAILBOXQ)); 3627 return (1); 3628 } 3629 } 3630 3631 /* Step 3: Dump the log to the DMP file as raw data. */ 3632 3633 /* Write a string to text file to direct the user to the DMP */ 3634 /* file for the actual log. */ 3635 status = 3636 emlxs_dump_string_txtfile(fpTxtFile, NV_LOG_INCLUDED_IN_DMP, 3637 LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 0); 3638 3639 /* Write the real log to the DMP file. */ 3640 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, logSize, DDI_DMA_SYNC_FORKERNEL); 3641 3642 status = 3643 emlxs_dump_host_block(fpDmpFile, mp->virt, logSize, 3644 SID_NON_VOLATILE_LOG, LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 3645 fSwap); 3646 3647 #ifdef FMA_SUPPORT 3648 if (emlxs_fm_check_dma_handle(hba, mp->dma_handle) 3649 != DDI_FM_OK) { 3650 EMLXS_MSGF(EMLXS_CONTEXT, 3651 &emlxs_invalid_dma_handle_msg, 3652 "emlxs_dump_saturn_log: hdl=%p", 3653 mp->dma_handle); 3654 status = 1; 3655 } 3656 #endif /* FMA_SUPPORT */ 3657 3658 emlxs_mem_buf_free(hba, mp); 3659 kmem_free(mbq, sizeof (MAILBOXQ)); 3660 return (status); 3661 3662 } /* emlxs_dump_saturn_log() */ 3663 3664 3665 static uint32_t 3666 emlxs_dump_tigershark_log( 3667 emlxs_hba_t *hba, 3668 emlxs_file_t *fpTxtFile, 3669 emlxs_file_t *fpCeeFile) 3670 { 3671 emlxs_port_t *port = &PPORT; 3672 uint32_t rval = 0; 3673 uint32_t offset; 3674 uint32_t log_size; 3675 uint32_t xfer_size; 3676 uint32_t buffer_size; 3677 uint8_t *buffer = NULL; 3678 uint8_t *bptr; 3679 uint8_t *payload; 3680 MAILBOXQ *mbq = NULL; 3681 MAILBOX4 *mb = NULL; 3682 MATCHMAP *mp = NULL; 3683 IOCTL_COMMON_MANAGE_FAT *fat; 3684 mbox_req_hdr_t *hdr_req; 3685 3686 if ((hba->model_info.chip != EMLXS_BE2_CHIP) && 3687 (hba->model_info.chip != EMLXS_BE3_CHIP)) { 3688 return (1); 3689 } 3690 3691 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3692 "Querying FAT..."); 3693 3694 mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), 3695 KM_SLEEP); 3696 3697 mb = (MAILBOX4*)mbq; 3698 3699 if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) + 3700 sizeof (IOCTL_COMMON_MANAGE_FAT) + BE_MAX_XFER_SIZE))) == NULL) { 3701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3702 "Unable to allocate FAT buffer."); 3703 3704 rval = 1; 3705 goto done; 3706 } 3707 3708 /* Query FAT */ 3709 mb->un.varSLIConfig.be.embedded = 0; 3710 mbq->nonembed = (void *)mp; 3711 mbq->mbox_cmpl = NULL; 3712 3713 mb->mbxCommand = MBX_SLI_CONFIG; 3714 mb->mbxOwner = OWN_HOST; 3715 3716 hdr_req = (mbox_req_hdr_t *)mp->virt; 3717 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 3718 hdr_req->opcode = COMMON_OPCODE_MANAGE_FAT; 3719 hdr_req->timeout = 0; 3720 hdr_req->req_length = sizeof (IOCTL_COMMON_MANAGE_FAT); 3721 3722 fat = (IOCTL_COMMON_MANAGE_FAT *)(hdr_req + 1); 3723 fat->params.request.fat_operation = QUERY_FAT; 3724 fat->params.request.read_log_offset = 0; 3725 fat->params.request.read_log_length = 0; 3726 fat->params.request.data_buffer_size = BE_MAX_XFER_SIZE; 3727 3728 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 3729 MBX_SUCCESS) { 3730 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3731 "FAT Query failed. status=%x", 3732 mb->mbxStatus); 3733 3734 rval = 1; 3735 goto done; 3736 } 3737 3738 log_size = fat->params.response.log_size; 3739 buffer_size = fat->params.response.log_size; 3740 3741 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3742 "FAT: log_size=%d", log_size); 3743 3744 if (buffer_size == 0) { 3745 goto done; 3746 } 3747 3748 if ((buffer = (uint8_t *)kmem_alloc( 3749 buffer_size, KM_NOSLEEP)) == NULL) { 3750 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3751 "Unable to allocate log buffer."); 3752 3753 rval = 1; 3754 goto done; 3755 } 3756 bzero(buffer, buffer_size); 3757 3758 /* Upload Log */ 3759 bptr = buffer; 3760 offset = 0; 3761 3762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3763 "Uploading log... (%d bytes)", log_size); 3764 3765 while (log_size) { 3766 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 3767 bzero((void *) mp->virt, mp->size); 3768 3769 xfer_size = min(BE_MAX_XFER_SIZE, log_size); 3770 3771 mb->un.varSLIConfig.be.embedded = 0; 3772 mbq->nonembed = (void *)mp; 3773 mbq->mbox_cmpl = NULL; 3774 3775 mb->mbxCommand = MBX_SLI_CONFIG; 3776 mb->mbxOwner = OWN_HOST; 3777 3778 hdr_req = (mbox_req_hdr_t *)mp->virt; 3779 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON; 3780 hdr_req->opcode = COMMON_OPCODE_MANAGE_FAT; 3781 hdr_req->timeout = 0; 3782 hdr_req->req_length = 3783 sizeof (IOCTL_COMMON_MANAGE_FAT) + xfer_size; 3784 3785 fat = (IOCTL_COMMON_MANAGE_FAT *)(hdr_req + 1); 3786 fat->params.request.fat_operation = RETRIEVE_FAT; 3787 fat->params.request.read_log_offset = offset; 3788 fat->params.request.read_log_length = xfer_size; 3789 fat->params.request.data_buffer_size = BE_MAX_XFER_SIZE; 3790 3791 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != 3792 MBX_SUCCESS) { 3793 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3794 "Failed to upload log. status=%x", 3795 mb->mbxStatus); 3796 3797 (void) emlxs_dump_string_txtfile(fpTxtFile, 3798 NV_LOG_NOT_INCLUDED_IN_FAT, 3799 LEGEND_NON_VOLATILE_LOG, 3800 LEGEND_NV_LOG_STATUS_ERROR, 0); 3801 3802 rval = 1; 3803 goto done; 3804 } 3805 3806 payload = (uint8_t *)(&fat->params.response.data_buffer); 3807 3808 BE_SWAP32_BCOPY(payload, bptr, xfer_size); 3809 3810 log_size -= xfer_size; 3811 offset += xfer_size; 3812 bptr += xfer_size; 3813 } 3814 3815 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3816 "Log upload complete."); 3817 3818 /* Write a string to text file to direct the user to the CEE */ 3819 /* file for the actual log. */ 3820 rval = 3821 emlxs_dump_string_txtfile(fpTxtFile, NV_LOG_INCLUDED_IN_FAT, 3822 LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 0); 3823 3824 3825 /* Write the log to the CEE file. */ 3826 /* First word is the log size */ 3827 bptr = buffer + sizeof (uint32_t); 3828 log_size = buffer_size - sizeof (uint32_t); 3829 rval = emlxs_dump_word_dmpfile(fpCeeFile, (uint8_t *)bptr, 3830 log_size, 0); 3831 3832 done: 3833 3834 if (mbq) { 3835 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 3836 } 3837 3838 if (mp) { 3839 emlxs_mem_buf_free(hba, mp); 3840 } 3841 3842 if (buffer) { 3843 kmem_free(buffer, buffer_size); 3844 } 3845 3846 if (rval == 0) { 3847 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3848 "Dump complete."); 3849 } 3850 3851 return (rval); 3852 3853 } /* emlxs_dump_tigershark_log() */ 3854 3855 3856 extern uint32_t 3857 emlxs_dump_user_event( 3858 emlxs_hba_t *hba) 3859 { 3860 emlxs_port_t *port = &PPORT; 3861 uint32_t status; 3862 emlxs_file_t *fpTxtFile; 3863 emlxs_file_t *fpDmpFile; 3864 emlxs_file_t *fpCeeFile; 3865 3866 mutex_enter(&EMLXS_DUMP_LOCK); 3867 3868 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3869 "User Event: Firmware core dump initiated..."); 3870 3871 status = 3872 emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile); 3873 if (status != 0) { 3874 mutex_exit(&EMLXS_DUMP_LOCK); 3875 return (1); 3876 } 3877 3878 (void) emlxs_dump_rev_info(hba, fpTxtFile, fpDmpFile); 3879 (void) emlxs_dump_hba_info(hba, fpTxtFile, fpDmpFile, DUMP_TYPE_USER); 3880 (void) emlxs_dump_parm_table(hba, fpTxtFile, fpDmpFile); 3881 (void) emlxs_dump_cfg_regions(hba, fpTxtFile, fpDmpFile); 3882 3883 if (hba->model_info.chip == EMLXS_SATURN_CHIP) { 3884 (void) emlxs_set_hba_mode(hba, DDI_ONDI); 3885 (void) emlxs_dump_saturn_log(hba, fpTxtFile, fpDmpFile); 3886 } 3887 3888 if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 3889 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 3890 (void) emlxs_dump_tigershark_log(hba, fpTxtFile, fpCeeFile); 3891 } 3892 3893 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) { 3894 (void) emlxs_set_hba_mode(hba, DDI_DIAGDI); 3895 } 3896 3897 (void) emlxs_dump_sli_interface(hba, fpTxtFile, fpDmpFile, 3898 DUMP_TYPE_USER); 3899 3900 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) { 3901 (void) emlxs_set_hba_mode(hba, DDI_WARMDI); 3902 } 3903 3904 (void) emlxs_dump_hba(hba, fpTxtFile, fpDmpFile); 3905 3906 (void) emlxs_set_hba_mode(hba, DDI_ONDI); 3907 3908 status = emlxs_menlo_set_mode(hba, MENLO_MAINTENANCE_MODE_ENABLE); 3909 if (status == 0) { 3910 (void) emlxs_dump_menlo_log(hba, fpCeeFile); 3911 (void) emlxs_menlo_set_mode(hba, 3912 MENLO_MAINTENANCE_MODE_DISABLE); 3913 } 3914 3915 (void) emlxs_dump_file_terminate(hba, fpTxtFile, fpDmpFile, fpCeeFile); 3916 (void) emlxs_dump_file_close(fpTxtFile, fpDmpFile, fpCeeFile); 3917 3918 mutex_exit(&EMLXS_DUMP_LOCK); 3919 return (0); 3920 3921 } /* emlxs_dump_user_event() */ 3922 3923 3924 extern uint32_t 3925 emlxs_dump_temp_event( 3926 emlxs_hba_t *hba, 3927 uint32_t tempType, 3928 uint32_t temp) 3929 { 3930 emlxs_port_t *port = &PPORT; 3931 uint32_t status; 3932 emlxs_file_t *fpTxtFile; 3933 3934 /* misc vars */ 3935 char sBuf1[512]; /* general purpose string buffer */ 3936 char sBuf2[256]; /* general purpose string buffer */ 3937 char sBuf3[256]; /* general purpose string buffer */ 3938 3939 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3940 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3941 "Temperature Event: type=%d temp=%d. "\ 3942 "Invalid SLI4 event.", 3943 tempType, temp); 3944 3945 return (1); 3946 } 3947 3948 mutex_enter(&EMLXS_DUMP_LOCK); 3949 3950 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 3951 "Temperature Event: type=%d temp=%d. "\ 3952 "Firmware core dump initiated...", 3953 tempType, temp); 3954 3955 status = emlxs_dump_file_create(hba, &fpTxtFile, 0, 0); 3956 if (status != 0) { 3957 mutex_exit(&EMLXS_DUMP_LOCK); 3958 return (1); 3959 } 3960 3961 /* Now generate the Dump */ 3962 /* Note: ignore return (status); if one part fails, */ 3963 /* keep trying to dump more stuff. */ 3964 3965 /* Write a warning at the top of the file */ 3966 (void) strcpy(sBuf1, "WARNING: HBA Temperature Event:\n"); 3967 switch (tempType) { 3968 case TEMP_TYPE_CRITICAL: 3969 (void) sprintf(sBuf2, " Event Type = %d (Critical)\n", 3970 tempType); 3971 break; 3972 case TEMP_TYPE_THRESHOLD: 3973 (void) sprintf(sBuf2, " Event Type = %d (Threshold)\n", 3974 tempType); 3975 break; 3976 case TEMP_TYPE_NORMAL: 3977 (void) sprintf(sBuf2, " Event Type = %d (Normal)\n", 3978 tempType); 3979 break; 3980 default: 3981 (void) sprintf(sBuf2, " Unknown Event Type = %d\n", tempType); 3982 break; 3983 } 3984 (void) sprintf(sBuf3, " Temperature = %d\n\n", temp); 3985 (void) strcat(sBuf1, sBuf2); 3986 (void) strcat(sBuf1, sBuf3); 3987 3988 (void) emlxs_dump_string_txtfile(fpTxtFile, sBuf1, 0, 0, 0); 3989 3990 (void) emlxs_dump_rev_info(hba, fpTxtFile, NULL); 3991 (void) emlxs_dump_hba_info(hba, fpTxtFile, NULL, DUMP_TYPE_TEMP); 3992 3993 (void) emlxs_dump_file_terminate(hba, fpTxtFile, NULL, NULL); 3994 (void) emlxs_dump_file_close(fpTxtFile, NULL, NULL); 3995 3996 mutex_exit(&EMLXS_DUMP_LOCK); 3997 return (0); 3998 3999 } /* emlxs_dump_temp_event() */ 4000 4001 4002 extern uint32_t 4003 emlxs_dump_drv_event( 4004 emlxs_hba_t *hba) 4005 { 4006 emlxs_port_t *port = &PPORT; 4007 uint32_t status; 4008 emlxs_file_t *fpTxtFile; 4009 emlxs_file_t *fpDmpFile; 4010 emlxs_file_t *fpCeeFile; 4011 4012 mutex_enter(&EMLXS_DUMP_LOCK); 4013 4014 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 4015 "Dump Event: Firmware core dump initiated..."); 4016 4017 status = 4018 emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile); 4019 if (status != 0) { 4020 mutex_exit(&EMLXS_DUMP_LOCK); 4021 return (1); 4022 } 4023 4024 if (hba->model_info.chip == EMLXS_SATURN_CHIP) { 4025 (void) emlxs_set_hba_mode(hba, DDI_ONDI); 4026 (void) emlxs_dump_saturn_log(hba, fpTxtFile, fpDmpFile); 4027 } 4028 4029 if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 4030 (hba->model_info.chip == EMLXS_BE3_CHIP)) { 4031 (void) emlxs_dump_tigershark_log(hba, fpTxtFile, fpCeeFile); 4032 } 4033 4034 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) { 4035 (void) emlxs_set_hba_mode(hba, DDI_DIAGDI); 4036 } 4037 4038 (void) emlxs_dump_sli_interface(hba, fpTxtFile, fpDmpFile, 4039 DUMP_TYPE_DRIVER); 4040 4041 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) { 4042 (void) emlxs_set_hba_mode(hba, DDI_WARMDI); 4043 } 4044 4045 (void) emlxs_dump_hba(hba, fpTxtFile, fpDmpFile); 4046 4047 (void) emlxs_set_hba_mode(hba, DDI_ONDI); 4048 4049 status = emlxs_menlo_set_mode(hba, MENLO_MAINTENANCE_MODE_ENABLE); 4050 if (status == 0) { 4051 (void) emlxs_dump_menlo_log(hba, fpCeeFile); 4052 } 4053 4054 /* Now generate the rest of the Dump */ 4055 (void) emlxs_dump_rev_info(hba, fpTxtFile, fpDmpFile); 4056 (void) emlxs_dump_hba_info(hba, fpTxtFile, fpDmpFile, DUMP_TYPE_DRIVER); 4057 (void) emlxs_dump_parm_table(hba, fpTxtFile, fpDmpFile); 4058 (void) emlxs_dump_cfg_regions(hba, fpTxtFile, fpDmpFile); 4059 4060 (void) emlxs_dump_file_terminate(hba, fpTxtFile, fpDmpFile, fpCeeFile); 4061 (void) emlxs_dump_file_close(fpTxtFile, fpDmpFile, fpCeeFile); 4062 4063 /* The last step of the Menlo Dump. */ 4064 (void) emlxs_menlo_reset(hba, MENLO_FW_OPERATIONAL); 4065 4066 (void) emlxs_set_hba_mode(hba, DDI_WARMDI); 4067 4068 mutex_exit(&EMLXS_DUMP_LOCK); 4069 4070 4071 return (0); 4072 4073 } /* emlxs_dump_drv_event() */ 4074 4075 4076 /* ARGSUSED */ 4077 extern void 4078 emlxs_dump_drv_thread(emlxs_hba_t *hba, 4079 void *arg1, void *arg2) 4080 { 4081 (void) emlxs_dump_drv_event(hba); 4082 4083 /* Clear the Dump flag */ 4084 mutex_enter(&EMLXS_PORT_LOCK); 4085 hba->flag &= ~FC_DUMP_ACTIVE; 4086 mutex_exit(&EMLXS_PORT_LOCK); 4087 4088 return; 4089 4090 } /* emlxs_dump_drv_thread() */ 4091 4092 4093 /* ARGSUSED */ 4094 extern void 4095 emlxs_dump_user_thread(emlxs_hba_t *hba, 4096 void *arg1, void *arg2) 4097 { 4098 (void) emlxs_dump_user_event(hba); 4099 4100 /* Clear the Dump flag */ 4101 mutex_enter(&EMLXS_PORT_LOCK); 4102 hba->flag &= ~FC_DUMP_ACTIVE; 4103 mutex_exit(&EMLXS_PORT_LOCK); 4104 4105 return; 4106 4107 } /* emlxs_dump_user_thread() */ 4108 4109 4110 /* ARGSUSED */ 4111 extern void 4112 emlxs_dump_temp_thread(emlxs_hba_t *hba, 4113 void *arg1, void *arg2) 4114 { 4115 dump_temp_event_t *temp_event = (dump_temp_event_t *)arg1; 4116 4117 (void) emlxs_dump_temp_event(temp_event->hba, temp_event->type, 4118 temp_event->temp); 4119 4120 /* Free the temp event object */ 4121 kmem_free(temp_event, sizeof (dump_temp_event_t)); 4122 4123 /* Clear the Dump flag */ 4124 mutex_enter(&EMLXS_PORT_LOCK); 4125 hba->flag &= ~FC_DUMP_ACTIVE; 4126 mutex_exit(&EMLXS_PORT_LOCK); 4127 4128 return; 4129 4130 } /* emlxs_dump_temp_thread() */ 4131 4132 4133 /* Schedules a dump thread */ 4134 /* temp_type and temp are only valid for type=EMLXS_TEMP_DUMP */ 4135 extern void 4136 emlxs_dump(emlxs_hba_t *hba, uint32_t type, uint32_t temp_type, uint32_t temp) 4137 { 4138 emlxs_port_t *port = &PPORT; 4139 dump_temp_event_t *temp_event = NULL; 4140 4141 mutex_enter(&EMLXS_PORT_LOCK); 4142 4143 /* Check if it is safe to dump */ 4144 if (!(hba->flag & FC_DUMP_SAFE)) { 4145 mutex_exit(&EMLXS_PORT_LOCK); 4146 4147 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 4148 "emlxs_dump: Dump disabled."); 4149 4150 return; 4151 } 4152 4153 /* Check if a dump is already in progess */ 4154 if (hba->flag & FC_DUMP_ACTIVE) { 4155 mutex_exit(&EMLXS_PORT_LOCK); 4156 4157 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 4158 "emlxs_dump: Dump already in progress."); 4159 4160 return; 4161 } 4162 4163 /* Prepare to schedule dump */ 4164 switch (type) { 4165 case EMLXS_DRV_DUMP: 4166 case EMLXS_USER_DUMP: 4167 break; 4168 4169 case EMLXS_TEMP_DUMP: 4170 temp_event = (dump_temp_event_t *)kmem_alloc( 4171 sizeof (dump_temp_event_t), KM_NOSLEEP); 4172 4173 if (temp_event == NULL) { 4174 mutex_exit(&EMLXS_PORT_LOCK); 4175 4176 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 4177 "emlxs_dump: Unable to allocate temp object."); 4178 4179 return; 4180 } 4181 4182 temp_event->hba = hba; 4183 temp_event->type = temp_type; 4184 temp_event->temp = temp; 4185 break; 4186 4187 default: 4188 mutex_exit(&EMLXS_PORT_LOCK); 4189 4190 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg, 4191 "emlxs_dump: Error: Unknown dump type. (%x)", 4192 type); 4193 4194 return; 4195 } 4196 4197 /* Set the Dump-in-progess flag */ 4198 hba->flag |= FC_DUMP_ACTIVE; 4199 mutex_exit(&EMLXS_PORT_LOCK); 4200 4201 /* Create a separate thread to run the dump event */ 4202 switch (type) { 4203 case EMLXS_DRV_DUMP: 4204 emlxs_thread_spawn(hba, emlxs_dump_drv_thread, NULL, NULL); 4205 break; 4206 4207 case EMLXS_TEMP_DUMP: 4208 emlxs_thread_spawn(hba, emlxs_dump_temp_thread, 4209 (void *)temp_event, NULL); 4210 break; 4211 4212 case EMLXS_USER_DUMP: 4213 emlxs_thread_spawn(hba, emlxs_dump_user_thread, NULL, NULL); 4214 break; 4215 } 4216 4217 return; 4218 4219 } /* emlxs_dump() */ 4220 4221 extern void 4222 emlxs_dump_wait(emlxs_hba_t *hba) 4223 { 4224 /* Wait for the Dump flag to clear */ 4225 while ((hba->flag & FC_DUMP_ACTIVE)) { 4226 DELAYMS(1000); 4227 } 4228 4229 } /* emlxs_dump_wait() */ 4230 4231 4232 #endif /* DUMP_SUPPORT */ 4233