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