1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* Copyright 2010 QLogic Corporation */ 23 24 /* 25 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 26 */ 27 28 #pragma ident "Copyright 2010 QLogic Corporation; ql_ioctl.c" 29 30 /* 31 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 32 * Fibre Channel Adapter (FCA) driver IOCTL source file. 33 * 34 * *********************************************************************** 35 * * ** 36 * * NOTICE ** 37 * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION ** 38 * * ALL RIGHTS RESERVED ** 39 * * ** 40 * *********************************************************************** 41 * 42 */ 43 44 #include <ql_apps.h> 45 #include <ql_api.h> 46 #include <ql_debug.h> 47 #include <ql_init.h> 48 #include <ql_ioctl.h> 49 #include <ql_mbx.h> 50 #include <ql_xioctl.h> 51 52 /* 53 * Local Function Prototypes. 54 */ 55 static int ql_busy_notification(ql_adapter_state_t *); 56 static int ql_idle_notification(ql_adapter_state_t *); 57 static int ql_get_feature_bits(ql_adapter_state_t *ha, uint16_t *features); 58 static int ql_set_feature_bits(ql_adapter_state_t *ha, uint16_t features); 59 static int ql_set_nvram_adapter_defaults(ql_adapter_state_t *ha); 60 static void ql_load_nvram(ql_adapter_state_t *ha, uint8_t addr, 61 uint16_t value); 62 static int ql_24xx_load_nvram(ql_adapter_state_t *, uint32_t, uint32_t); 63 static int ql_adm_op(ql_adapter_state_t *, void *, int); 64 static int ql_adm_adapter_info(ql_adapter_state_t *, ql_adm_op_t *, int); 65 static int ql_adm_extended_logging(ql_adapter_state_t *, ql_adm_op_t *); 66 static int ql_adm_device_list(ql_adapter_state_t *, ql_adm_op_t *, int); 67 static int ql_adm_update_properties(ql_adapter_state_t *); 68 static int ql_adm_prop_update_int(ql_adapter_state_t *, ql_adm_op_t *, int); 69 static int ql_adm_loop_reset(ql_adapter_state_t *); 70 static int ql_adm_fw_dump(ql_adapter_state_t *, ql_adm_op_t *, void *, int); 71 static int ql_adm_nvram_dump(ql_adapter_state_t *, ql_adm_op_t *, int); 72 static int ql_adm_nvram_load(ql_adapter_state_t *, ql_adm_op_t *, int); 73 static int ql_adm_flash_load(ql_adapter_state_t *, ql_adm_op_t *, int); 74 static int ql_adm_vpd_dump(ql_adapter_state_t *, ql_adm_op_t *, int); 75 static int ql_adm_vpd_load(ql_adapter_state_t *, ql_adm_op_t *, int); 76 static int ql_adm_vpd_gettag(ql_adapter_state_t *, ql_adm_op_t *, int); 77 static int ql_adm_updfwmodule(ql_adapter_state_t *, ql_adm_op_t *, int); 78 static uint8_t *ql_vpd_findtag(ql_adapter_state_t *, uint8_t *, int8_t *); 79 80 /* ************************************************************************ */ 81 /* cb_ops functions */ 82 /* ************************************************************************ */ 83 84 /* 85 * ql_open 86 * opens device 87 * 88 * Input: 89 * dev_p = device pointer 90 * flags = open flags 91 * otype = open type 92 * cred_p = credentials pointer 93 * 94 * Returns: 95 * 0 = success 96 * 97 * Context: 98 * Kernel context. 99 */ 100 /* ARGSUSED */ 101 int 102 ql_open(dev_t *dev_p, int flags, int otyp, cred_t *cred_p) 103 { 104 ql_adapter_state_t *ha; 105 int rval = 0; 106 107 ha = ddi_get_soft_state(ql_state, (int32_t)getminor(*dev_p)); 108 if (ha == NULL) { 109 QL_PRINT_2(CE_CONT, "failed, no adapter\n"); 110 return (ENXIO); 111 } 112 113 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 114 115 /* Allow only character opens */ 116 if (otyp != OTYP_CHR) { 117 QL_PRINT_2(CE_CONT, "(%d): failed, open type\n", 118 ha->instance); 119 return (EINVAL); 120 } 121 122 ADAPTER_STATE_LOCK(ha); 123 if (flags & FEXCL && ha->flags & QL_OPENED) { 124 ADAPTER_STATE_UNLOCK(ha); 125 rval = EBUSY; 126 } else { 127 ha->flags |= QL_OPENED; 128 ADAPTER_STATE_UNLOCK(ha); 129 } 130 131 if (rval != 0) { 132 EL(ha, "failed, rval = %xh\n", rval); 133 } else { 134 /*EMPTY*/ 135 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 136 } 137 return (rval); 138 } 139 140 /* 141 * ql_close 142 * opens device 143 * 144 * Input: 145 * dev_p = device pointer 146 * flags = open flags 147 * otype = open type 148 * cred_p = credentials pointer 149 * 150 * Returns: 151 * 0 = success 152 * 153 * Context: 154 * Kernel context. 155 */ 156 /* ARGSUSED */ 157 int 158 ql_close(dev_t dev, int flags, int otyp, cred_t *cred_p) 159 { 160 ql_adapter_state_t *ha; 161 int rval = 0; 162 163 ha = ddi_get_soft_state(ql_state, (int32_t)getminor(dev)); 164 if (ha == NULL) { 165 QL_PRINT_2(CE_CONT, "failed, no adapter\n"); 166 return (ENXIO); 167 } 168 169 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 170 171 if (otyp != OTYP_CHR) { 172 QL_PRINT_2(CE_CONT, "(%d): failed, open type\n", 173 ha->instance); 174 return (EINVAL); 175 } 176 177 ADAPTER_STATE_LOCK(ha); 178 ha->flags &= ~QL_OPENED; 179 ADAPTER_STATE_UNLOCK(ha); 180 181 if (rval != 0) { 182 EL(ha, "failed, rval = %xh\n", rval); 183 } else { 184 /*EMPTY*/ 185 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 186 } 187 return (rval); 188 } 189 190 /* 191 * ql_ioctl 192 * control a character device 193 * 194 * Input: 195 * dev = device number 196 * cmd = function to perform 197 * arg = data type varies with request 198 * mode = flags 199 * cred_p = credentials pointer 200 * rval_p = pointer to result value 201 * 202 * Returns: 203 * 0 = success 204 * 205 * Context: 206 * Kernel context. 207 */ 208 /* ARGSUSED */ 209 int 210 ql_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p, 211 int *rval_p) 212 { 213 ql_adapter_state_t *ha; 214 int rval = 0; 215 216 if (ddi_in_panic()) { 217 QL_PRINT_2(CE_CONT, "ql_ioctl: ddi_in_panic exit\n"); 218 return (ENOPROTOOPT); 219 } 220 221 ha = ddi_get_soft_state(ql_state, (int32_t)getminor(dev)); 222 if (ha == NULL) { 223 QL_PRINT_2(CE_CONT, "failed, no adapter\n"); 224 return (ENXIO); 225 } 226 227 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 228 229 /* 230 * Quick clean exit for qla2x00 foapi calls which are 231 * not supported in qlc. 232 */ 233 if (cmd >= QL_FOAPI_START && cmd <= QL_FOAPI_END) { 234 QL_PRINT_9(CE_CONT, "failed, fo api not supported\n"); 235 return (ENOTTY); 236 } 237 238 /* PWR management busy. */ 239 rval = ql_busy_notification(ha); 240 if (rval != FC_SUCCESS) { 241 EL(ha, "failed, ql_busy_notification\n"); 242 return (ENXIO); 243 } 244 245 rval = ql_xioctl(ha, cmd, arg, mode, cred_p, rval_p); 246 if (rval == ENOPROTOOPT || rval == EINVAL) { 247 switch (cmd) { 248 case QL_GET_ADAPTER_FEATURE_BITS: { 249 uint16_t bits; 250 251 rval = ql_get_feature_bits(ha, &bits); 252 253 if (!rval && ddi_copyout((void *)&bits, (void *)arg, 254 sizeof (bits), mode)) { 255 rval = EFAULT; 256 } 257 break; 258 } 259 260 case QL_SET_ADAPTER_FEATURE_BITS: { 261 uint16_t bits; 262 263 if (ddi_copyin((void *)arg, (void *)&bits, 264 sizeof (bits), mode)) { 265 rval = EFAULT; 266 break; 267 } 268 269 rval = ql_set_feature_bits(ha, bits); 270 break; 271 } 272 273 case QL_SET_ADAPTER_NVRAM_DEFAULTS: 274 rval = ql_set_nvram_adapter_defaults(ha); 275 break; 276 277 case QL_UTIL_LOAD: 278 rval = ql_nv_util_load(ha, (void *)arg, mode); 279 break; 280 281 case QL_UTIL_DUMP: 282 rval = ql_nv_util_dump(ha, (void *)arg, mode); 283 break; 284 285 case QL_ADM_OP: 286 rval = ql_adm_op(ha, (void *)arg, mode); 287 break; 288 289 default: 290 EL(ha, "unknown command = %d\n", cmd); 291 rval = ENOTTY; 292 break; 293 } 294 } 295 296 /* PWR management idle. */ 297 (void) ql_idle_notification(ha); 298 299 if (rval != 0) { 300 /* 301 * Don't show failures caused by pps polling for 302 * non-existant virtual ports. 303 */ 304 if (cmd != EXT_CC_VPORT_CMD) { 305 EL(ha, "failed, cmd=%d rval=%d\n", cmd, rval); 306 } 307 } else { 308 /*EMPTY*/ 309 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 310 } 311 return (rval); 312 } 313 314 /* 315 * ql_busy_notification 316 * Adapter busy notification. 317 * 318 * Input: 319 * ha = adapter state pointer. 320 * 321 * Returns: 322 * FC_SUCCESS 323 * FC_FAILURE 324 * 325 * Context: 326 * Kernel context. 327 */ 328 static int 329 ql_busy_notification(ql_adapter_state_t *ha) 330 { 331 if (!ha->pm_capable) { 332 return (FC_SUCCESS); 333 } 334 335 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 336 337 QL_PM_LOCK(ha); 338 ha->busy++; 339 QL_PM_UNLOCK(ha); 340 341 if (pm_busy_component(ha->dip, 0) != DDI_SUCCESS) { 342 QL_PM_LOCK(ha); 343 ha->busy--; 344 QL_PM_UNLOCK(ha); 345 346 EL(ha, "pm_busy_component failed = %xh\n", FC_FAILURE); 347 return (FC_FAILURE); 348 } 349 350 QL_PM_LOCK(ha); 351 if (ha->power_level != PM_LEVEL_D0) { 352 QL_PM_UNLOCK(ha); 353 if (pm_raise_power(ha->dip, 0, 1) != DDI_SUCCESS) { 354 QL_PM_LOCK(ha); 355 ha->busy--; 356 QL_PM_UNLOCK(ha); 357 return (FC_FAILURE); 358 } 359 } else { 360 QL_PM_UNLOCK(ha); 361 } 362 363 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 364 365 return (FC_SUCCESS); 366 } 367 368 /* 369 * ql_idle_notification 370 * Adapter idle notification. 371 * 372 * Input: 373 * ha = adapter state pointer. 374 * 375 * Returns: 376 * FC_SUCCESS 377 * FC_FAILURE 378 * 379 * Context: 380 * Kernel context. 381 */ 382 static int 383 ql_idle_notification(ql_adapter_state_t *ha) 384 { 385 if (!ha->pm_capable) { 386 return (FC_SUCCESS); 387 } 388 389 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 390 391 if (pm_idle_component(ha->dip, 0) != DDI_SUCCESS) { 392 EL(ha, "pm_idle_component failed = %xh\n", FC_FAILURE); 393 return (FC_FAILURE); 394 } 395 396 QL_PM_LOCK(ha); 397 ha->busy--; 398 QL_PM_UNLOCK(ha); 399 400 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 401 402 return (FC_SUCCESS); 403 } 404 405 /* 406 * Get adapter feature bits from NVRAM 407 */ 408 static int 409 ql_get_feature_bits(ql_adapter_state_t *ha, uint16_t *features) 410 { 411 int count; 412 volatile uint16_t data; 413 uint32_t nv_cmd; 414 uint32_t start_addr; 415 int rval; 416 uint32_t offset = offsetof(nvram_t, adapter_features); 417 418 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 419 420 if (CFG_IST(ha, CFG_CTRL_24258081)) { 421 EL(ha, "Not supported for 24xx\n"); 422 return (EINVAL); 423 } 424 425 /* 426 * The offset can't be greater than max of 8 bits and 427 * the following code breaks if the offset isn't at 428 * 2 byte boundary. 429 */ 430 rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA); 431 if (rval != QL_SUCCESS) { 432 EL(ha, "failed, ql_lock_nvram=%xh\n", rval); 433 return (EIO); 434 } 435 436 /* 437 * Have the most significant 3 bits represent the read operation 438 * followed by the 8 bits representing the offset at which we 439 * are going to perform the read operation 440 */ 441 offset >>= 1; 442 offset += start_addr; 443 nv_cmd = (offset << 16) | NV_READ_OP; 444 nv_cmd <<= 5; 445 446 /* 447 * Select the chip and feed the command and address 448 */ 449 for (count = 0; count < 11; count++) { 450 if (nv_cmd & BIT_31) { 451 ql_nv_write(ha, NV_DATA_OUT); 452 } else { 453 ql_nv_write(ha, 0); 454 } 455 nv_cmd <<= 1; 456 } 457 458 *features = 0; 459 for (count = 0; count < 16; count++) { 460 WRT16_IO_REG(ha, nvram, NV_SELECT | NV_CLOCK); 461 ql_nv_delay(); 462 463 data = RD16_IO_REG(ha, nvram); 464 *features <<= 1; 465 if (data & NV_DATA_IN) { 466 *features = (uint16_t)(*features | 0x1); 467 } 468 469 WRT16_IO_REG(ha, nvram, NV_SELECT); 470 ql_nv_delay(); 471 } 472 473 /* 474 * Deselect the chip 475 */ 476 WRT16_IO_REG(ha, nvram, NV_DESELECT); 477 478 ql_release_nvram(ha); 479 480 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 481 482 return (0); 483 } 484 485 /* 486 * Set adapter feature bits in NVRAM 487 */ 488 static int 489 ql_set_feature_bits(ql_adapter_state_t *ha, uint16_t features) 490 { 491 int rval; 492 uint32_t count; 493 nvram_t *nv; 494 uint16_t *wptr; 495 uint8_t *bptr; 496 uint8_t csum; 497 uint32_t start_addr; 498 499 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 500 501 if (CFG_IST(ha, CFG_CTRL_24258081)) { 502 EL(ha, "Not supported for 24xx\n"); 503 return (EINVAL); 504 } 505 506 nv = kmem_zalloc(sizeof (*nv), KM_SLEEP); 507 if (nv == NULL) { 508 EL(ha, "failed, kmem_zalloc\n"); 509 return (ENOMEM); 510 } 511 512 rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA); 513 if (rval != QL_SUCCESS) { 514 EL(ha, "failed, ql_lock_nvram=%xh\n", rval); 515 kmem_free(nv, sizeof (*nv)); 516 return (EIO); 517 } 518 rval = 0; 519 520 /* 521 * Read off the whole NVRAM 522 */ 523 wptr = (uint16_t *)nv; 524 csum = 0; 525 for (count = 0; count < sizeof (nvram_t) / 2; count++) { 526 *wptr = (uint16_t)ql_get_nvram_word(ha, count + start_addr); 527 csum = (uint8_t)(csum + (uint8_t)*wptr); 528 csum = (uint8_t)(csum + (uint8_t)(*wptr >> 8)); 529 wptr++; 530 } 531 532 /* 533 * If the checksum is BAD then fail it right here. 534 */ 535 if (csum) { 536 kmem_free(nv, sizeof (*nv)); 537 ql_release_nvram(ha); 538 return (EBADF); 539 } 540 541 nv->adapter_features[0] = (uint8_t)((features & 0xFF00) >> 8); 542 nv->adapter_features[1] = (uint8_t)(features & 0xFF); 543 544 /* 545 * Recompute the chesksum now 546 */ 547 bptr = (uint8_t *)nv; 548 for (count = 0; count < sizeof (nvram_t) - 1; count++) { 549 csum = (uint8_t)(csum + *bptr++); 550 } 551 csum = (uint8_t)(~csum + 1); 552 nv->checksum = csum; 553 554 /* 555 * Now load the NVRAM 556 */ 557 wptr = (uint16_t *)nv; 558 for (count = 0; count < sizeof (nvram_t) / 2; count++) { 559 ql_load_nvram(ha, (uint8_t)(count + start_addr), *wptr++); 560 } 561 562 /* 563 * Read NVRAM and verify the contents 564 */ 565 wptr = (uint16_t *)nv; 566 csum = 0; 567 for (count = 0; count < sizeof (nvram_t) / 2; count++) { 568 if (ql_get_nvram_word(ha, count + start_addr) != *wptr) { 569 rval = EIO; 570 break; 571 } 572 csum = (uint8_t)(csum + (uint8_t)*wptr); 573 csum = (uint8_t)(csum + (uint8_t)(*wptr >> 8)); 574 wptr++; 575 } 576 577 if (csum) { 578 rval = EINVAL; 579 } 580 581 kmem_free(nv, sizeof (*nv)); 582 ql_release_nvram(ha); 583 584 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 585 586 return (rval); 587 } 588 589 /* 590 * Fix this function to update just feature bits and checksum in NVRAM 591 */ 592 static int 593 ql_set_nvram_adapter_defaults(ql_adapter_state_t *ha) 594 { 595 int rval; 596 uint32_t count; 597 uint32_t start_addr; 598 599 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 600 601 rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA); 602 if (rval != QL_SUCCESS) { 603 EL(ha, "failed, ql_lock_nvram=%xh\n", rval); 604 return (EIO); 605 } 606 rval = 0; 607 608 if (CFG_IST(ha, CFG_CTRL_24258081)) { 609 nvram_24xx_t *nv; 610 uint32_t *longptr; 611 uint32_t csum = 0; 612 613 nv = kmem_zalloc(sizeof (*nv), KM_SLEEP); 614 if (nv == NULL) { 615 EL(ha, "failed, kmem_zalloc\n"); 616 return (ENOMEM); 617 } 618 619 nv->nvram_version[0] = LSB(ICB_24XX_VERSION); 620 nv->nvram_version[1] = MSB(ICB_24XX_VERSION); 621 622 nv->version[0] = 1; 623 nv->max_frame_length[1] = 8; 624 nv->execution_throttle[0] = 16; 625 nv->login_retry_count[0] = 8; 626 627 nv->firmware_options_1[0] = BIT_2 | BIT_1; 628 nv->firmware_options_1[1] = BIT_5; 629 nv->firmware_options_2[0] = BIT_5; 630 nv->firmware_options_2[1] = BIT_4; 631 nv->firmware_options_3[1] = BIT_6; 632 633 /* 634 * Set default host adapter parameters 635 */ 636 nv->host_p[0] = BIT_4 | BIT_1; 637 nv->host_p[1] = BIT_3 | BIT_2; 638 nv->reset_delay = 5; 639 nv->max_luns_per_target[0] = 128; 640 nv->port_down_retry_count[0] = 30; 641 nv->link_down_timeout[0] = 30; 642 643 /* 644 * compute the chesksum now 645 */ 646 longptr = (uint32_t *)nv; 647 csum = 0; 648 for (count = 0; count < (sizeof (nvram_24xx_t)/4)-1; count++) { 649 csum += *longptr; 650 longptr++; 651 } 652 csum = (uint32_t)(~csum + 1); 653 LITTLE_ENDIAN_32((long)csum); 654 *longptr = csum; 655 656 /* 657 * Now load the NVRAM 658 */ 659 longptr = (uint32_t *)nv; 660 for (count = 0; count < sizeof (nvram_24xx_t) / 4; count++) { 661 (void) ql_24xx_load_nvram(ha, 662 (uint32_t)(count + start_addr), *longptr++); 663 } 664 665 /* 666 * Read NVRAM and verify the contents 667 */ 668 csum = 0; 669 longptr = (uint32_t *)nv; 670 for (count = 0; count < sizeof (nvram_24xx_t) / 4; count++) { 671 rval = ql_24xx_read_flash(ha, count + start_addr, 672 longptr); 673 if (rval != QL_SUCCESS) { 674 EL(ha, "24xx_read_flash failed=%xh\n", rval); 675 break; 676 } 677 csum += *longptr; 678 } 679 680 if (csum) { 681 rval = EINVAL; 682 } 683 kmem_free(nv, sizeof (nvram_24xx_t)); 684 } else { 685 nvram_t *nv; 686 uint16_t *wptr; 687 uint8_t *bptr; 688 uint8_t csum; 689 690 nv = kmem_zalloc(sizeof (*nv), KM_SLEEP); 691 if (nv == NULL) { 692 EL(ha, "failed, kmem_zalloc\n"); 693 return (ENOMEM); 694 } 695 /* 696 * Set default initialization control block. 697 */ 698 nv->parameter_block_version = ICB_VERSION; 699 nv->firmware_options[0] = BIT_4 | BIT_3 | BIT_2 | BIT_1; 700 nv->firmware_options[1] = BIT_7 | BIT_5 | BIT_2; 701 702 nv->max_frame_length[1] = 4; 703 nv->max_iocb_allocation[1] = 1; 704 nv->execution_throttle[0] = 16; 705 nv->login_retry_count = 8; 706 nv->port_name[0] = 33; 707 nv->port_name[3] = 224; 708 nv->port_name[4] = 139; 709 nv->login_timeout = 4; 710 711 /* 712 * Set default host adapter parameters 713 */ 714 nv->host_p[0] = BIT_1; 715 nv->host_p[1] = BIT_2; 716 nv->reset_delay = 5; 717 nv->port_down_retry_count = 8; 718 nv->maximum_luns_per_target[0] = 8; 719 720 /* 721 * compute the chesksum now 722 */ 723 bptr = (uint8_t *)nv; 724 csum = 0; 725 for (count = 0; count < sizeof (nvram_t) - 1; count++) { 726 csum = (uint8_t)(csum + *bptr++); 727 } 728 csum = (uint8_t)(~csum + 1); 729 nv->checksum = csum; 730 731 /* 732 * Now load the NVRAM 733 */ 734 wptr = (uint16_t *)nv; 735 for (count = 0; count < sizeof (nvram_t) / 2; count++) { 736 ql_load_nvram(ha, (uint8_t)(count + start_addr), 737 *wptr++); 738 } 739 740 /* 741 * Read NVRAM and verify the contents 742 */ 743 wptr = (uint16_t *)nv; 744 csum = 0; 745 for (count = 0; count < sizeof (nvram_t) / 2; count++) { 746 if (ql_get_nvram_word(ha, count + start_addr) != 747 *wptr) { 748 rval = EIO; 749 break; 750 } 751 csum = (uint8_t)(csum + (uint8_t)*wptr); 752 csum = (uint8_t)(csum + (uint8_t)(*wptr >> 8)); 753 wptr++; 754 } 755 if (csum) { 756 rval = EINVAL; 757 } 758 kmem_free(nv, sizeof (*nv)); 759 } 760 ql_release_nvram(ha); 761 762 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 763 764 return (rval); 765 } 766 767 static void 768 ql_load_nvram(ql_adapter_state_t *ha, uint8_t addr, uint16_t value) 769 { 770 int count; 771 volatile uint16_t word; 772 volatile uint32_t nv_cmd; 773 774 ql_nv_write(ha, NV_DATA_OUT); 775 ql_nv_write(ha, 0); 776 ql_nv_write(ha, 0); 777 778 for (word = 0; word < 8; word++) { 779 ql_nv_write(ha, NV_DATA_OUT); 780 } 781 782 /* 783 * Deselect the chip 784 */ 785 WRT16_IO_REG(ha, nvram, NV_DESELECT); 786 ql_nv_delay(); 787 788 /* 789 * Erase Location 790 */ 791 nv_cmd = (addr << 16) | NV_ERASE_OP; 792 nv_cmd <<= 5; 793 for (count = 0; count < 11; count++) { 794 if (nv_cmd & BIT_31) { 795 ql_nv_write(ha, NV_DATA_OUT); 796 } else { 797 ql_nv_write(ha, 0); 798 } 799 nv_cmd <<= 1; 800 } 801 802 /* 803 * Wait for Erase to Finish 804 */ 805 WRT16_IO_REG(ha, nvram, NV_DESELECT); 806 ql_nv_delay(); 807 WRT16_IO_REG(ha, nvram, NV_SELECT); 808 word = 0; 809 while ((word & NV_DATA_IN) == 0) { 810 ql_nv_delay(); 811 word = RD16_IO_REG(ha, nvram); 812 } 813 WRT16_IO_REG(ha, nvram, NV_DESELECT); 814 ql_nv_delay(); 815 816 /* 817 * Write data now 818 */ 819 nv_cmd = (addr << 16) | NV_WRITE_OP; 820 nv_cmd |= value; 821 nv_cmd <<= 5; 822 for (count = 0; count < 27; count++) { 823 if (nv_cmd & BIT_31) { 824 ql_nv_write(ha, NV_DATA_OUT); 825 } else { 826 ql_nv_write(ha, 0); 827 } 828 nv_cmd <<= 1; 829 } 830 831 /* 832 * Wait for NVRAM to become ready 833 */ 834 WRT16_IO_REG(ha, nvram, NV_DESELECT); 835 ql_nv_delay(); 836 WRT16_IO_REG(ha, nvram, NV_SELECT); 837 word = 0; 838 while ((word & NV_DATA_IN) == 0) { 839 ql_nv_delay(); 840 word = RD16_IO_REG(ha, nvram); 841 } 842 WRT16_IO_REG(ha, nvram, NV_DESELECT); 843 ql_nv_delay(); 844 845 /* 846 * Disable writes 847 */ 848 ql_nv_write(ha, NV_DATA_OUT); 849 for (count = 0; count < 10; count++) { 850 ql_nv_write(ha, 0); 851 } 852 853 /* 854 * Deselect the chip now 855 */ 856 WRT16_IO_REG(ha, nvram, NV_DESELECT); 857 } 858 859 /* 860 * ql_24xx_load_nvram 861 * Enable NVRAM and writes a 32bit word to ISP24xx NVRAM. 862 * 863 * Input: 864 * ha: adapter state pointer. 865 * addr: NVRAM address. 866 * value: data. 867 * 868 * Returns: 869 * ql local function return status code. 870 * 871 * Context: 872 * Kernel context. 873 */ 874 static int 875 ql_24xx_load_nvram(ql_adapter_state_t *ha, uint32_t addr, uint32_t value) 876 { 877 int rval; 878 879 /* Enable flash write. */ 880 if (!(CFG_IST(ha, CFG_CTRL_8081))) { 881 WRT32_IO_REG(ha, ctrl_status, 882 RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE); 883 RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */ 884 } 885 886 /* Disable NVRAM write-protection. */ 887 if (CFG_IST(ha, CFG_CTRL_2422)) { 888 (void) ql_24xx_write_flash(ha, NVRAM_CONF_ADDR | 0x101, 0); 889 } else { 890 if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) { 891 EL(ha, "unprotect_flash failed, rval=%xh\n", rval); 892 return (rval); 893 } 894 } 895 896 /* Write to flash. */ 897 rval = ql_24xx_write_flash(ha, addr, value); 898 899 /* Enable NVRAM write-protection. */ 900 if (CFG_IST(ha, CFG_CTRL_2422)) { 901 /* TODO: Check if 0x8c is correct -- sb: 0x9c ? */ 902 (void) ql_24xx_write_flash(ha, NVRAM_CONF_ADDR | 0x101, 0x8c); 903 } else { 904 ql_24xx_protect_flash(ha); 905 } 906 907 /* Disable flash write. */ 908 if (!(CFG_IST(ha, CFG_CTRL_81XX))) { 909 WRT32_IO_REG(ha, ctrl_status, 910 RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE); 911 RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */ 912 } 913 914 return (rval); 915 } 916 917 /* 918 * ql_nv_util_load 919 * Loads NVRAM from application. 920 * 921 * Input: 922 * ha = adapter state pointer. 923 * bp = user buffer address. 924 * 925 * Returns: 926 * 927 * Context: 928 * Kernel context. 929 */ 930 int 931 ql_nv_util_load(ql_adapter_state_t *ha, void *bp, int mode) 932 { 933 uint8_t cnt; 934 void *nv; 935 uint16_t *wptr; 936 uint16_t data; 937 uint32_t start_addr, *lptr, data32; 938 nvram_t *nptr; 939 int rval; 940 941 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 942 943 if ((nv = kmem_zalloc(ha->nvram_cache->size, KM_SLEEP)) == NULL) { 944 EL(ha, "failed, kmem_zalloc\n"); 945 return (ENOMEM); 946 } 947 948 if (ddi_copyin(bp, nv, ha->nvram_cache->size, mode) != 0) { 949 EL(ha, "Buffer copy failed\n"); 950 kmem_free(nv, ha->nvram_cache->size); 951 return (EFAULT); 952 } 953 954 /* See if the buffer passed to us looks sane */ 955 nptr = (nvram_t *)nv; 956 if (nptr->id[0] != 'I' || nptr->id[1] != 'S' || nptr->id[2] != 'P' || 957 nptr->id[3] != ' ') { 958 EL(ha, "failed, buffer sanity check\n"); 959 kmem_free(nv, ha->nvram_cache->size); 960 return (EINVAL); 961 } 962 963 /* Quiesce I/O */ 964 if (ql_stall_driver(ha, 0) != QL_SUCCESS) { 965 EL(ha, "ql_stall_driver failed\n"); 966 kmem_free(nv, ha->nvram_cache->size); 967 return (EBUSY); 968 } 969 970 rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA); 971 if (rval != QL_SUCCESS) { 972 EL(ha, "failed, ql_lock_nvram=%xh\n", rval); 973 kmem_free(nv, ha->nvram_cache->size); 974 ql_restart_driver(ha); 975 return (EIO); 976 } 977 978 /* Load NVRAM. */ 979 if (CFG_IST(ha, CFG_CTRL_258081)) { 980 GLOBAL_HW_UNLOCK(); 981 start_addr &= ~ha->flash_data_addr; 982 start_addr <<= 2; 983 if ((rval = ql_r_m_w_flash(ha, bp, ha->nvram_cache->size, 984 start_addr, mode)) != QL_SUCCESS) { 985 EL(ha, "nvram load failed, rval = %0xh\n", rval); 986 } 987 GLOBAL_HW_LOCK(); 988 } else if (CFG_IST(ha, CFG_CTRL_2422)) { 989 lptr = (uint32_t *)nv; 990 for (cnt = 0; cnt < ha->nvram_cache->size / 4; cnt++) { 991 data32 = *lptr++; 992 LITTLE_ENDIAN_32(&data32); 993 rval = ql_24xx_load_nvram(ha, cnt + start_addr, 994 data32); 995 if (rval != QL_SUCCESS) { 996 EL(ha, "failed, 24xx_load_nvram=%xh\n", rval); 997 break; 998 } 999 } 1000 } else { 1001 wptr = (uint16_t *)nv; 1002 for (cnt = 0; cnt < ha->nvram_cache->size / 2; cnt++) { 1003 data = *wptr++; 1004 LITTLE_ENDIAN_16(&data); 1005 ql_load_nvram(ha, (uint8_t)(cnt + start_addr), data); 1006 } 1007 } 1008 /* switch to the new one */ 1009 NVRAM_CACHE_LOCK(ha); 1010 1011 kmem_free(ha->nvram_cache->cache, ha->nvram_cache->size); 1012 ha->nvram_cache->cache = (void *)nptr; 1013 1014 NVRAM_CACHE_UNLOCK(ha); 1015 1016 ql_release_nvram(ha); 1017 ql_restart_driver(ha); 1018 1019 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1020 1021 if (rval == QL_SUCCESS) { 1022 return (0); 1023 } 1024 1025 return (EFAULT); 1026 } 1027 1028 /* 1029 * ql_nv_util_dump 1030 * Dumps NVRAM to application. 1031 * 1032 * Input: 1033 * ha = adapter state pointer. 1034 * bp = user buffer address. 1035 * 1036 * Returns: 1037 * 1038 * Context: 1039 * Kernel context. 1040 */ 1041 int 1042 ql_nv_util_dump(ql_adapter_state_t *ha, void *bp, int mode) 1043 { 1044 uint32_t start_addr; 1045 int rval2, rval = 0; 1046 1047 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1048 1049 if (ha->nvram_cache == NULL || 1050 ha->nvram_cache->size == NULL || 1051 ha->nvram_cache->cache == NULL) { 1052 EL(ha, "failed, kmem_zalloc\n"); 1053 return (ENOMEM); 1054 } else if (ha->nvram_cache->valid != 1) { 1055 1056 /* Quiesce I/O */ 1057 if (ql_stall_driver(ha, 0) != QL_SUCCESS) { 1058 EL(ha, "ql_stall_driver failed\n"); 1059 return (EBUSY); 1060 } 1061 1062 rval2 = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA); 1063 if (rval2 != QL_SUCCESS) { 1064 EL(ha, "failed, ql_lock_nvram=%xh\n", rval2); 1065 ql_restart_driver(ha); 1066 return (EIO); 1067 } 1068 NVRAM_CACHE_LOCK(ha); 1069 1070 rval2 = ql_get_nvram(ha, ha->nvram_cache->cache, 1071 start_addr, ha->nvram_cache->size); 1072 if (rval2 != QL_SUCCESS) { 1073 rval = rval2; 1074 } else { 1075 ha->nvram_cache->valid = 1; 1076 EL(ha, "nvram cache now valid."); 1077 } 1078 1079 NVRAM_CACHE_UNLOCK(ha); 1080 1081 ql_release_nvram(ha); 1082 ql_restart_driver(ha); 1083 1084 if (rval != 0) { 1085 EL(ha, "failed to dump nvram, rval=%x\n", rval); 1086 return (rval); 1087 } 1088 } 1089 1090 if (ddi_copyout(ha->nvram_cache->cache, bp, 1091 ha->nvram_cache->size, mode) != 0) { 1092 EL(ha, "Buffer copy failed\n"); 1093 return (EFAULT); 1094 } 1095 1096 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1097 1098 return (0); 1099 } 1100 1101 int 1102 ql_get_nvram(ql_adapter_state_t *ha, void *dest_addr, uint32_t src_addr, 1103 uint32_t size) 1104 { 1105 int rval = QL_SUCCESS; 1106 int cnt; 1107 /* Dump NVRAM. */ 1108 if (CFG_IST(ha, CFG_CTRL_24258081)) { 1109 uint32_t *lptr = (uint32_t *)dest_addr; 1110 1111 for (cnt = 0; cnt < size / 4; cnt++) { 1112 rval = ql_24xx_read_flash(ha, src_addr++, lptr); 1113 if (rval != QL_SUCCESS) { 1114 EL(ha, "read_flash failed=%xh\n", rval); 1115 rval = EAGAIN; 1116 break; 1117 } 1118 LITTLE_ENDIAN_32(lptr); 1119 lptr++; 1120 } 1121 } else { 1122 uint16_t data; 1123 uint16_t *wptr = (uint16_t *)dest_addr; 1124 1125 for (cnt = 0; cnt < size / 2; cnt++) { 1126 data = (uint16_t)ql_get_nvram_word(ha, cnt + 1127 src_addr); 1128 LITTLE_ENDIAN_16(&data); 1129 *wptr++ = data; 1130 } 1131 } 1132 return (rval); 1133 } 1134 1135 /* 1136 * ql_vpd_load 1137 * Loads VPD from application. 1138 * 1139 * Input: 1140 * ha = adapter state pointer. 1141 * bp = user buffer address. 1142 * 1143 * Returns: 1144 * 1145 * Context: 1146 * Kernel context. 1147 */ 1148 int 1149 ql_vpd_load(ql_adapter_state_t *ha, void *bp, int mode) 1150 { 1151 uint8_t cnt; 1152 uint8_t *vpd, *vpdptr, *vbuf; 1153 uint32_t start_addr, vpd_size, *lptr, data32; 1154 int rval; 1155 1156 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1157 1158 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 1159 EL(ha, "unsupported adapter feature\n"); 1160 return (ENOTSUP); 1161 } 1162 1163 vpd_size = QL_24XX_VPD_SIZE; 1164 1165 if ((vpd = kmem_zalloc(vpd_size, KM_SLEEP)) == NULL) { 1166 EL(ha, "failed, kmem_zalloc\n"); 1167 return (ENOMEM); 1168 } 1169 1170 if (ddi_copyin(bp, vpd, vpd_size, mode) != 0) { 1171 EL(ha, "Buffer copy failed\n"); 1172 kmem_free(vpd, vpd_size); 1173 return (EFAULT); 1174 } 1175 1176 /* Sanity check the user supplied data via checksum */ 1177 if ((vpdptr = ql_vpd_findtag(ha, vpd, "RV")) == NULL) { 1178 EL(ha, "vpd RV tag missing\n"); 1179 kmem_free(vpd, vpd_size); 1180 return (EINVAL); 1181 } 1182 1183 vpdptr += 3; 1184 cnt = 0; 1185 vbuf = vpd; 1186 while (vbuf <= vpdptr) { 1187 cnt += *vbuf++; 1188 } 1189 if (cnt != 0) { 1190 EL(ha, "mismatched checksum, cal=%xh, passed=%xh\n", 1191 (uint8_t)cnt, (uintptr_t)vpdptr); 1192 kmem_free(vpd, vpd_size); 1193 return (EINVAL); 1194 } 1195 1196 /* Quiesce I/O */ 1197 if (ql_stall_driver(ha, 0) != QL_SUCCESS) { 1198 EL(ha, "ql_stall_driver failed\n"); 1199 kmem_free(vpd, vpd_size); 1200 return (EBUSY); 1201 } 1202 1203 rval = ql_lock_nvram(ha, &start_addr, LNF_VPD_DATA); 1204 if (rval != QL_SUCCESS) { 1205 EL(ha, "failed, ql_lock_nvram=%xh\n", rval); 1206 kmem_free(vpd, vpd_size); 1207 ql_restart_driver(ha); 1208 return (EIO); 1209 } 1210 1211 /* Load VPD. */ 1212 if (CFG_IST(ha, CFG_CTRL_258081)) { 1213 GLOBAL_HW_UNLOCK(); 1214 start_addr &= ~ha->flash_data_addr; 1215 start_addr <<= 2; 1216 if ((rval = ql_r_m_w_flash(ha, bp, vpd_size, start_addr, 1217 mode)) != QL_SUCCESS) { 1218 EL(ha, "vpd load error: %xh\n", rval); 1219 } 1220 GLOBAL_HW_LOCK(); 1221 } else { 1222 lptr = (uint32_t *)vpd; 1223 for (cnt = 0; cnt < vpd_size / 4; cnt++) { 1224 data32 = *lptr++; 1225 LITTLE_ENDIAN_32(&data32); 1226 rval = ql_24xx_load_nvram(ha, cnt + start_addr, 1227 data32); 1228 if (rval != QL_SUCCESS) { 1229 EL(ha, "failed, 24xx_load_nvram=%xh\n", rval); 1230 break; 1231 } 1232 } 1233 } 1234 1235 kmem_free(vpd, vpd_size); 1236 1237 /* Update the vcache */ 1238 CACHE_LOCK(ha); 1239 1240 if (rval != QL_SUCCESS) { 1241 EL(ha, "failed, load\n"); 1242 } else if ((ha->vcache == NULL) && ((ha->vcache = 1243 kmem_zalloc(vpd_size, KM_SLEEP)) == NULL)) { 1244 EL(ha, "failed, kmem_zalloc2\n"); 1245 } else if (ddi_copyin(bp, ha->vcache, vpd_size, mode) != 0) { 1246 EL(ha, "Buffer copy2 failed\n"); 1247 kmem_free(ha->vcache, vpd_size); 1248 ha->vcache = NULL; 1249 } 1250 1251 CACHE_UNLOCK(ha); 1252 1253 ql_release_nvram(ha); 1254 ql_restart_driver(ha); 1255 1256 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1257 1258 if (rval == QL_SUCCESS) { 1259 return (0); 1260 } 1261 1262 return (EFAULT); 1263 } 1264 1265 /* 1266 * ql_vpd_dump 1267 * Dumps VPD to application buffer. 1268 * 1269 * Input: 1270 * ha = adapter state pointer. 1271 * bp = user buffer address. 1272 * 1273 * Returns: 1274 * 1275 * Context: 1276 * Kernel context. 1277 */ 1278 int 1279 ql_vpd_dump(ql_adapter_state_t *ha, void *bp, int mode) 1280 { 1281 uint8_t cnt; 1282 void *vpd; 1283 uint32_t start_addr, vpd_size, *lptr; 1284 int rval = 0; 1285 1286 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1287 1288 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 1289 EL(ha, "unsupported adapter feature\n"); 1290 return (EACCES); 1291 } 1292 1293 vpd_size = QL_24XX_VPD_SIZE; 1294 1295 CACHE_LOCK(ha); 1296 1297 if (ha->vcache != NULL) { 1298 /* copy back the vpd cache data */ 1299 if (ddi_copyout(ha->vcache, bp, vpd_size, mode) != 0) { 1300 EL(ha, "Buffer copy failed\n"); 1301 rval = EFAULT; 1302 } 1303 CACHE_UNLOCK(ha); 1304 return (rval); 1305 } 1306 1307 if ((vpd = kmem_zalloc(vpd_size, KM_SLEEP)) == NULL) { 1308 CACHE_UNLOCK(ha); 1309 EL(ha, "failed, kmem_zalloc\n"); 1310 return (ENOMEM); 1311 } 1312 1313 /* Quiesce I/O */ 1314 if (ql_stall_driver(ha, 0) != QL_SUCCESS) { 1315 CACHE_UNLOCK(ha); 1316 EL(ha, "ql_stall_driver failed\n"); 1317 kmem_free(vpd, vpd_size); 1318 return (EBUSY); 1319 } 1320 1321 rval = ql_lock_nvram(ha, &start_addr, LNF_VPD_DATA); 1322 if (rval != QL_SUCCESS) { 1323 CACHE_UNLOCK(ha); 1324 EL(ha, "failed, ql_lock_nvram=%xh\n", rval); 1325 kmem_free(vpd, vpd_size); 1326 ql_restart_driver(ha); 1327 return (EIO); 1328 } 1329 1330 /* Dump VPD. */ 1331 lptr = (uint32_t *)vpd; 1332 1333 for (cnt = 0; cnt < vpd_size / 4; cnt++) { 1334 rval = ql_24xx_read_flash(ha, start_addr++, lptr); 1335 if (rval != QL_SUCCESS) { 1336 EL(ha, "read_flash failed=%xh\n", rval); 1337 rval = EAGAIN; 1338 break; 1339 } 1340 LITTLE_ENDIAN_32(lptr); 1341 lptr++; 1342 } 1343 1344 ql_release_nvram(ha); 1345 ql_restart_driver(ha); 1346 1347 if (ddi_copyout(vpd, bp, vpd_size, mode) != 0) { 1348 CACHE_UNLOCK(ha); 1349 EL(ha, "Buffer copy failed\n"); 1350 kmem_free(vpd, vpd_size); 1351 return (EFAULT); 1352 } 1353 1354 ha->vcache = vpd; 1355 1356 CACHE_UNLOCK(ha); 1357 1358 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1359 1360 if (rval != QL_SUCCESS) { 1361 return (EFAULT); 1362 } else { 1363 return (0); 1364 } 1365 } 1366 1367 /* 1368 * ql_vpd_findtag 1369 * Search the passed vpd buffer for the requested VPD tag type. 1370 * 1371 * Input: 1372 * ha = adapter state pointer. 1373 * vpdbuf = Pointer to start of the buffer to search 1374 * op = VPD opcode to find (must be NULL terminated). 1375 * 1376 * Returns: 1377 * Pointer to the opcode in the buffer if opcode found. 1378 * NULL if opcode is not found. 1379 * 1380 * Context: 1381 * Kernel context. 1382 */ 1383 static uint8_t * 1384 ql_vpd_findtag(ql_adapter_state_t *ha, uint8_t *vpdbuf, int8_t *opcode) 1385 { 1386 uint8_t *vpd = vpdbuf; 1387 uint8_t *end = vpdbuf + QL_24XX_VPD_SIZE; 1388 uint32_t found = 0; 1389 1390 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1391 1392 if (vpdbuf == NULL || opcode == NULL) { 1393 EL(ha, "null parameter passed!\n"); 1394 return (NULL); 1395 } 1396 1397 while (vpd < end) { 1398 1399 /* check for end of vpd */ 1400 if (vpd[0] == VPD_TAG_END) { 1401 if (opcode[0] == VPD_TAG_END) { 1402 found = 1; 1403 } else { 1404 found = 0; 1405 } 1406 break; 1407 } 1408 1409 /* check opcode */ 1410 if (bcmp(opcode, vpd, strlen(opcode)) == 0) { 1411 /* found opcode requested */ 1412 found = 1; 1413 break; 1414 } 1415 1416 /* 1417 * Didn't find the opcode, so calculate start of 1418 * next tag. Depending on the current tag type, 1419 * the length field can be 1 or 2 bytes 1420 */ 1421 if (!(strncmp((char *)vpd, (char *)VPD_TAG_PRODID, 1))) { 1422 vpd += (vpd[2] << 8) + vpd[1] + 3; 1423 } else if (*vpd == VPD_TAG_LRT || *vpd == VPD_TAG_LRTC) { 1424 vpd += 3; 1425 } else { 1426 vpd += vpd[2] +3; 1427 } 1428 } 1429 1430 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1431 1432 return (found == 1 ? vpd : NULL); 1433 } 1434 1435 /* 1436 * ql_vpd_lookup 1437 * Return the VPD data for the request VPD tag 1438 * 1439 * Input: 1440 * ha = adapter state pointer. 1441 * opcode = VPD opcode to find (must be NULL terminated). 1442 * bp = Pointer to returned data buffer. 1443 * bplen = Length of returned data buffer. 1444 * 1445 * Returns: 1446 * Length of data copied into returned data buffer. 1447 * >0 = VPD data field (NULL terminated) 1448 * 0 = no data. 1449 * -1 = Could not find opcode in vpd buffer / error. 1450 * 1451 * Context: 1452 * Kernel context. 1453 * 1454 * NB: The opcode buffer and the bp buffer *could* be the same buffer! 1455 * 1456 */ 1457 int32_t 1458 ql_vpd_lookup(ql_adapter_state_t *ha, uint8_t *opcode, uint8_t *bp, 1459 int32_t bplen) 1460 { 1461 uint8_t *vpd; 1462 uint8_t *vpdbuf; 1463 int32_t len = -1; 1464 1465 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1466 1467 if (opcode == NULL || bp == NULL || bplen < 1) { 1468 EL(ha, "invalid parameter passed: opcode=%ph, " 1469 "bp=%ph, bplen=%xh\n", opcode, bp, bplen); 1470 return (len); 1471 } 1472 1473 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 1474 return (len); 1475 } 1476 1477 if ((vpdbuf = (uint8_t *)kmem_zalloc(QL_24XX_VPD_SIZE, 1478 KM_SLEEP)) == NULL) { 1479 EL(ha, "unable to allocate vpd memory\n"); 1480 return (len); 1481 } 1482 1483 if ((ql_vpd_dump(ha, vpdbuf, (int)FKIOCTL)) != 0) { 1484 kmem_free(vpdbuf, QL_24XX_VPD_SIZE); 1485 EL(ha, "unable to retrieve VPD data\n"); 1486 return (len); 1487 } 1488 1489 if ((vpd = ql_vpd_findtag(ha, vpdbuf, (int8_t *)opcode)) != NULL) { 1490 /* 1491 * Found the tag 1492 */ 1493 if (*opcode == VPD_TAG_END || *opcode == VPD_TAG_LRT || 1494 *opcode == VPD_TAG_LRTC) { 1495 /* 1496 * we found it, but the tag doesn't have a data 1497 * field. 1498 */ 1499 len = 0; 1500 } else if (!(strncmp((char *)vpd, (char *) 1501 VPD_TAG_PRODID, 1))) { 1502 len = vpd[2] << 8; 1503 len += vpd[1]; 1504 } else { 1505 len = vpd[2]; 1506 } 1507 1508 /* 1509 * make sure that the vpd len doesn't exceed the 1510 * vpd end 1511 */ 1512 if (vpd+len > vpdbuf + QL_24XX_VPD_SIZE) { 1513 EL(ha, "vpd tag len (%xh) exceeds vpd buffer " 1514 "length\n", len); 1515 len = -1; 1516 } 1517 } 1518 1519 if (len >= 0) { 1520 /* 1521 * make sure we don't exceed callers buffer space len 1522 */ 1523 if (len > bplen) { 1524 len = bplen-1; 1525 } 1526 1527 /* copy the data back */ 1528 (void) strncpy((int8_t *)bp, (int8_t *)(vpd+3), (int64_t)len); 1529 bp[len] = NULL; 1530 } else { 1531 /* error -- couldn't find tag */ 1532 bp[0] = NULL; 1533 if (opcode[1] != NULL) { 1534 EL(ha, "unable to find tag '%s'\n", opcode); 1535 } else { 1536 EL(ha, "unable to find tag '%xh'\n", opcode[0]); 1537 } 1538 } 1539 1540 kmem_free(vpdbuf, QL_24XX_VPD_SIZE); 1541 1542 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1543 1544 return (len); 1545 } 1546 1547 /* 1548 * ql_r_m_w_flash 1549 * Read modify write from user space to flash. 1550 * 1551 * Input: 1552 * ha: adapter state pointer. 1553 * dp: source byte pointer. 1554 * bc: byte count. 1555 * faddr: flash byte address. 1556 * mode: flags. 1557 * 1558 * Returns: 1559 * ql local function return status code. 1560 * 1561 * Context: 1562 * Kernel context. 1563 */ 1564 int 1565 ql_r_m_w_flash(ql_adapter_state_t *ha, caddr_t dp, uint32_t bc, uint32_t faddr, 1566 int mode) 1567 { 1568 uint8_t *bp; 1569 uint32_t xfer, bsize, saddr, ofst; 1570 int rval = 0; 1571 1572 QL_PRINT_9(CE_CONT, "(%d): started, dp=%ph, faddr=%xh, bc=%xh\n", 1573 ha->instance, (void *)dp, faddr, bc); 1574 1575 bsize = ha->xioctl->fdesc.block_size; 1576 saddr = faddr & ~(bsize - 1); 1577 ofst = faddr & (bsize - 1); 1578 1579 if ((bp = kmem_zalloc(bsize, KM_SLEEP)) == NULL) { 1580 EL(ha, "kmem_zalloc=null\n"); 1581 return (QL_MEMORY_ALLOC_FAILED); 1582 } 1583 1584 while (bc) { 1585 xfer = bc > bsize ? bsize : bc; 1586 if (ofst + xfer > bsize) { 1587 xfer = bsize - ofst; 1588 } 1589 QL_PRINT_9(CE_CONT, "(%d): dp=%ph, saddr=%xh, bc=%xh, " 1590 "ofst=%xh, xfer=%xh\n", ha->instance, (void *)dp, saddr, 1591 bc, ofst, xfer); 1592 1593 if (ofst || xfer < bsize) { 1594 /* Dump Flash sector. */ 1595 if ((rval = ql_dump_fcode(ha, bp, bsize, saddr)) != 1596 QL_SUCCESS) { 1597 EL(ha, "dump_flash status=%x\n", rval); 1598 break; 1599 } 1600 } 1601 1602 /* Set new data. */ 1603 if ((rval = ddi_copyin(dp, (caddr_t)(bp + ofst), xfer, 1604 mode)) != 0) { 1605 EL(ha, "ddi_copyin status=%xh, dp=%ph, ofst=%xh, " 1606 "xfer=%xh\n", rval, (void *)dp, ofst, xfer); 1607 rval = QL_FUNCTION_FAILED; 1608 break; 1609 } 1610 1611 /* Write to flash. */ 1612 if ((rval = ql_load_fcode(ha, bp, bsize, saddr)) != 1613 QL_SUCCESS) { 1614 EL(ha, "load_flash status=%x\n", rval); 1615 break; 1616 } 1617 bc -= xfer; 1618 dp += xfer; 1619 saddr += bsize; 1620 ofst = 0; 1621 } 1622 1623 kmem_free(bp, bsize); 1624 1625 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1626 1627 return (rval); 1628 } 1629 1630 /* 1631 * ql_adm_op 1632 * Performs qladm utility operations 1633 * 1634 * Input: 1635 * ha: adapter state pointer. 1636 * arg: driver_op_t structure pointer. 1637 * mode: flags. 1638 * 1639 * Returns: 1640 * 1641 * Context: 1642 * Kernel context. 1643 */ 1644 static int 1645 ql_adm_op(ql_adapter_state_t *ha, void *arg, int mode) 1646 { 1647 ql_adm_op_t dop; 1648 int rval = 0; 1649 1650 if (ddi_copyin(arg, &dop, sizeof (ql_adm_op_t), mode) != 0) { 1651 EL(ha, "failed, driver_op_t ddi_copyin\n"); 1652 return (EFAULT); 1653 } 1654 1655 QL_PRINT_9(CE_CONT, "(%d): started, cmd=%xh, buffer=%llx," 1656 " length=%xh, option=%xh\n", ha->instance, dop.cmd, dop.buffer, 1657 dop.length, dop.option); 1658 1659 switch (dop.cmd) { 1660 case QL_ADAPTER_INFO: 1661 rval = ql_adm_adapter_info(ha, &dop, mode); 1662 break; 1663 1664 case QL_EXTENDED_LOGGING: 1665 rval = ql_adm_extended_logging(ha, &dop); 1666 break; 1667 1668 case QL_LOOP_RESET: 1669 rval = ql_adm_loop_reset(ha); 1670 break; 1671 1672 case QL_DEVICE_LIST: 1673 rval = ql_adm_device_list(ha, &dop, mode); 1674 break; 1675 1676 case QL_PROP_UPDATE_INT: 1677 rval = ql_adm_prop_update_int(ha, &dop, mode); 1678 break; 1679 1680 case QL_UPDATE_PROPERTIES: 1681 rval = ql_adm_update_properties(ha); 1682 break; 1683 1684 case QL_FW_DUMP: 1685 rval = ql_adm_fw_dump(ha, &dop, arg, mode); 1686 break; 1687 1688 case QL_NVRAM_LOAD: 1689 rval = ql_adm_nvram_load(ha, &dop, mode); 1690 break; 1691 1692 case QL_NVRAM_DUMP: 1693 rval = ql_adm_nvram_dump(ha, &dop, mode); 1694 break; 1695 1696 case QL_FLASH_LOAD: 1697 rval = ql_adm_flash_load(ha, &dop, mode); 1698 break; 1699 1700 case QL_VPD_LOAD: 1701 rval = ql_adm_vpd_load(ha, &dop, mode); 1702 break; 1703 1704 case QL_VPD_DUMP: 1705 rval = ql_adm_vpd_dump(ha, &dop, mode); 1706 break; 1707 1708 case QL_VPD_GETTAG: 1709 rval = ql_adm_vpd_gettag(ha, &dop, mode); 1710 break; 1711 1712 case QL_UPD_FWMODULE: 1713 rval = ql_adm_updfwmodule(ha, &dop, mode); 1714 break; 1715 1716 default: 1717 EL(ha, "unsupported driver op cmd: %x\n", dop.cmd); 1718 return (EINVAL); 1719 } 1720 1721 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1722 1723 return (rval); 1724 } 1725 1726 /* 1727 * ql_adm_adapter_info 1728 * Performs qladm QL_ADAPTER_INFO command 1729 * 1730 * Input: 1731 * ha: adapter state pointer. 1732 * dop: ql_adm_op_t structure pointer. 1733 * mode: flags. 1734 * 1735 * Returns: 1736 * 1737 * Context: 1738 * Kernel context. 1739 */ 1740 static int 1741 ql_adm_adapter_info(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 1742 { 1743 ql_adapter_info_t hba; 1744 uint8_t *dp; 1745 uint32_t length; 1746 int rval, i; 1747 1748 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1749 1750 hba.device_id = ha->device_id; 1751 1752 dp = CFG_IST(ha, CFG_CTRL_24258081) ? 1753 &ha->init_ctrl_blk.cb24.port_name[0] : 1754 &ha->init_ctrl_blk.cb.port_name[0]; 1755 bcopy(dp, hba.wwpn, 8); 1756 1757 hba.d_id = ha->d_id.b24; 1758 1759 if (ha->xioctl->fdesc.flash_size == 0 && 1760 !(CFG_IST(ha, CFG_CTRL_2200) && !ha->subven_id)) { 1761 if (ql_stall_driver(ha, 0) != QL_SUCCESS) { 1762 EL(ha, "ql_stall_driver failed\n"); 1763 return (EBUSY); 1764 } 1765 1766 if ((rval = ql_setup_fcache(ha)) != QL_SUCCESS) { 1767 EL(ha, "ql_setup_flash failed=%xh\n", rval); 1768 if (rval == QL_FUNCTION_TIMEOUT) { 1769 return (EBUSY); 1770 } 1771 return (EIO); 1772 } 1773 1774 /* Resume I/O */ 1775 if (CFG_IST(ha, CFG_CTRL_24258081)) { 1776 ql_restart_driver(ha); 1777 } else { 1778 EL(ha, "isp_abort_needed for restart\n"); 1779 ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 1780 DRIVER_STALL); 1781 } 1782 } 1783 hba.flash_size = ha->xioctl->fdesc.flash_size; 1784 1785 (void) strcpy(hba.driver_ver, QL_VERSION); 1786 1787 (void) sprintf(hba.fw_ver, "%d.%d.%d", ha->fw_major_version, 1788 ha->fw_minor_version, ha->fw_subminor_version); 1789 1790 bzero(hba.fcode_ver, sizeof (hba.fcode_ver)); 1791 1792 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 1793 rval = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip, 1794 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version", (caddr_t)&dp, &i); 1795 length = i; 1796 if (rval != DDI_PROP_SUCCESS) { 1797 EL(ha, "failed, ddi_getlongprop=%xh\n", rval); 1798 } else { 1799 if (length > (uint32_t)sizeof (hba.fcode_ver)) { 1800 length = sizeof (hba.fcode_ver) - 1; 1801 } 1802 bcopy((void *)dp, (void *)hba.fcode_ver, length); 1803 kmem_free(dp, length); 1804 } 1805 1806 if (ddi_copyout((void *)&hba, (void *)(uintptr_t)dop->buffer, 1807 dop->length, mode) != 0) { 1808 EL(ha, "failed, ddi_copyout\n"); 1809 return (EFAULT); 1810 } 1811 1812 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1813 1814 return (0); 1815 } 1816 1817 /* 1818 * ql_adm_extended_logging 1819 * Performs qladm QL_EXTENDED_LOGGING command 1820 * 1821 * Input: 1822 * ha: adapter state pointer. 1823 * dop: ql_adm_op_t structure pointer. 1824 * 1825 * Returns: 1826 * 1827 * Context: 1828 * Kernel context. 1829 */ 1830 static int 1831 ql_adm_extended_logging(ql_adapter_state_t *ha, ql_adm_op_t *dop) 1832 { 1833 char prop_name[MAX_PROP_LENGTH]; 1834 int rval; 1835 1836 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1837 1838 (void) sprintf(prop_name, "hba%d-extended-logging", ha->instance); 1839 1840 /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/ 1841 rval = ddi_prop_update_int(DDI_DEV_T_NONE, ha->dip, prop_name, 1842 (int)dop->option); 1843 if (rval != DDI_PROP_SUCCESS) { 1844 EL(ha, "failed, prop_update = %xh\n", rval); 1845 return (EINVAL); 1846 } else { 1847 dop->option ? 1848 (ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING) : 1849 (ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING); 1850 } 1851 1852 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1853 1854 return (0); 1855 } 1856 1857 /* 1858 * ql_adm_loop_reset 1859 * Performs qladm QL_LOOP_RESET command 1860 * 1861 * Input: 1862 * ha: adapter state pointer. 1863 * 1864 * Returns: 1865 * 1866 * Context: 1867 * Kernel context. 1868 */ 1869 static int 1870 ql_adm_loop_reset(ql_adapter_state_t *ha) 1871 { 1872 int rval; 1873 1874 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1875 1876 if (ha->task_daemon_flags & LOOP_DOWN) { 1877 (void) ql_full_login_lip(ha); 1878 } else if ((rval = ql_full_login_lip(ha)) != QL_SUCCESS) { 1879 EL(ha, "failed, ql_initiate_lip=%xh\n", rval); 1880 return (EIO); 1881 } 1882 1883 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1884 1885 return (0); 1886 } 1887 1888 /* 1889 * ql_adm_device_list 1890 * Performs qladm QL_DEVICE_LIST command 1891 * 1892 * Input: 1893 * ha: adapter state pointer. 1894 * dop: ql_adm_op_t structure pointer. 1895 * mode: flags. 1896 * 1897 * Returns: 1898 * 1899 * Context: 1900 * Kernel context. 1901 */ 1902 static int 1903 ql_adm_device_list(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 1904 { 1905 ql_device_info_t dev; 1906 ql_link_t *link; 1907 ql_tgt_t *tq; 1908 uint32_t index, cnt; 1909 1910 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1911 1912 cnt = 0; 1913 dev.address = 0xffffffff; 1914 1915 /* Scan port list for requested target and fill in the values */ 1916 for (link = NULL, index = 0; 1917 index < DEVICE_HEAD_LIST_SIZE && link == NULL; index++) { 1918 for (link = ha->dev[index].first; link != NULL; 1919 link = link->next) { 1920 tq = link->base_address; 1921 1922 if (!VALID_TARGET_ID(ha, tq->loop_id)) { 1923 continue; 1924 } 1925 if (cnt != dop->option) { 1926 cnt++; 1927 continue; 1928 } 1929 /* fill in the values */ 1930 bcopy(tq->port_name, dev.wwpn, 8); 1931 dev.address = tq->d_id.b24; 1932 dev.loop_id = tq->loop_id; 1933 if (tq->flags & TQF_TAPE_DEVICE) { 1934 dev.type = FCT_TAPE; 1935 } else if (tq->flags & TQF_INITIATOR_DEVICE) { 1936 dev.type = FCT_INITIATOR; 1937 } else { 1938 dev.type = FCT_TARGET; 1939 } 1940 break; 1941 } 1942 } 1943 1944 if (ddi_copyout((void *)&dev, (void *)(uintptr_t)dop->buffer, 1945 dop->length, mode) != 0) { 1946 EL(ha, "failed, ddi_copyout\n"); 1947 return (EFAULT); 1948 } 1949 1950 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 1951 1952 return (0); 1953 } 1954 1955 /* 1956 * ql_adm_update_properties 1957 * Performs qladm QL_UPDATE_PROPERTIES command 1958 * 1959 * Input: 1960 * ha: adapter state pointer. 1961 * 1962 * Returns: 1963 * 1964 * Context: 1965 * Kernel context. 1966 */ 1967 static int 1968 ql_adm_update_properties(ql_adapter_state_t *ha) 1969 { 1970 ql_comb_init_cb_t init_ctrl_blk; 1971 ql_comb_ip_init_cb_t ip_init_ctrl_blk; 1972 1973 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 1974 1975 /* Stall driver instance. */ 1976 (void) ql_stall_driver(ha, 0); 1977 1978 /* Save init control blocks. */ 1979 bcopy(&ha->init_ctrl_blk, &init_ctrl_blk, sizeof (ql_comb_init_cb_t)); 1980 bcopy(&ha->ip_init_ctrl_blk, &ip_init_ctrl_blk, 1981 sizeof (ql_comb_ip_init_cb_t)); 1982 1983 /* Update PCI configration. */ 1984 (void) ql_pci_sbus_config(ha); 1985 1986 /* Get configuration properties. */ 1987 (void) ql_nvram_config(ha); 1988 1989 /* Check for init firmware required. */ 1990 if (bcmp(&ha->init_ctrl_blk, &init_ctrl_blk, 1991 sizeof (ql_comb_init_cb_t)) != 0 || 1992 bcmp(&ha->ip_init_ctrl_blk, &ip_init_ctrl_blk, 1993 sizeof (ql_comb_ip_init_cb_t)) != 0) { 1994 1995 EL(ha, "isp_abort_needed\n"); 1996 ha->loop_down_timer = LOOP_DOWN_TIMER_START; 1997 TASK_DAEMON_LOCK(ha); 1998 ha->task_daemon_flags |= LOOP_DOWN | ISP_ABORT_NEEDED; 1999 TASK_DAEMON_UNLOCK(ha); 2000 } 2001 2002 /* Update AEN queue. */ 2003 if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) { 2004 ql_enqueue_aen(ha, MBA_PORT_UPDATE, NULL); 2005 } 2006 2007 /* Restart driver instance. */ 2008 ql_restart_driver(ha); 2009 2010 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2011 2012 return (0); 2013 } 2014 2015 /* 2016 * ql_adm_prop_update_int 2017 * Performs qladm QL_PROP_UPDATE_INT command 2018 * 2019 * Input: 2020 * ha: adapter state pointer. 2021 * dop: ql_adm_op_t structure pointer. 2022 * mode: flags. 2023 * 2024 * Returns: 2025 * 2026 * Context: 2027 * Kernel context. 2028 */ 2029 static int 2030 ql_adm_prop_update_int(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2031 { 2032 char *prop_name; 2033 int rval; 2034 2035 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2036 2037 prop_name = kmem_zalloc(dop->length, KM_SLEEP); 2038 if (prop_name == NULL) { 2039 EL(ha, "failed, kmem_zalloc\n"); 2040 return (ENOMEM); 2041 } 2042 2043 if (ddi_copyin((void *)(uintptr_t)dop->buffer, prop_name, dop->length, 2044 mode) != 0) { 2045 EL(ha, "failed, prop_name ddi_copyin\n"); 2046 kmem_free(prop_name, dop->length); 2047 return (EFAULT); 2048 } 2049 2050 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 2051 if ((rval = ddi_prop_update_int(DDI_DEV_T_NONE, ha->dip, prop_name, 2052 (int)dop->option)) != DDI_PROP_SUCCESS) { 2053 EL(ha, "failed, prop_update=%xh\n", rval); 2054 kmem_free(prop_name, dop->length); 2055 return (EINVAL); 2056 } 2057 2058 kmem_free(prop_name, dop->length); 2059 2060 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2061 2062 return (0); 2063 } 2064 2065 /* 2066 * ql_adm_fw_dump 2067 * Performs qladm QL_FW_DUMP command 2068 * 2069 * Input: 2070 * ha: adapter state pointer. 2071 * dop: ql_adm_op_t structure pointer. 2072 * udop: user space ql_adm_op_t structure pointer. 2073 * mode: flags. 2074 * 2075 * Returns: 2076 * 2077 * Context: 2078 * Kernel context. 2079 */ 2080 static int 2081 ql_adm_fw_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, void *udop, int mode) 2082 { 2083 caddr_t dmp; 2084 2085 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2086 2087 if (dop->length < ha->risc_dump_size) { 2088 EL(ha, "failed, incorrect length=%xh, size=%xh\n", 2089 dop->length, ha->risc_dump_size); 2090 return (EINVAL); 2091 } 2092 2093 if (ha->ql_dump_state & QL_DUMP_VALID) { 2094 dmp = kmem_zalloc(ha->risc_dump_size, KM_SLEEP); 2095 if (dmp == NULL) { 2096 EL(ha, "failed, kmem_zalloc\n"); 2097 return (ENOMEM); 2098 } 2099 2100 dop->length = (uint32_t)ql_ascii_fw_dump(ha, dmp); 2101 if (ddi_copyout((void *)dmp, (void *)(uintptr_t)dop->buffer, 2102 dop->length, mode) != 0) { 2103 EL(ha, "failed, ddi_copyout\n"); 2104 kmem_free(dmp, ha->risc_dump_size); 2105 return (EFAULT); 2106 } 2107 2108 kmem_free(dmp, ha->risc_dump_size); 2109 ha->ql_dump_state |= QL_DUMP_UPLOADED; 2110 2111 } else { 2112 EL(ha, "failed, no dump file\n"); 2113 dop->length = 0; 2114 } 2115 2116 if (ddi_copyout(dop, udop, sizeof (ql_adm_op_t), mode) != 0) { 2117 EL(ha, "failed, driver_op_t ddi_copyout\n"); 2118 return (EFAULT); 2119 } 2120 2121 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2122 2123 return (0); 2124 } 2125 2126 /* 2127 * ql_adm_nvram_dump 2128 * Performs qladm QL_NVRAM_DUMP command 2129 * 2130 * Input: 2131 * ha: adapter state pointer. 2132 * dop: ql_adm_op_t structure pointer. 2133 * mode: flags. 2134 * 2135 * Returns: 2136 * 2137 * Context: 2138 * Kernel context. 2139 */ 2140 static int 2141 ql_adm_nvram_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2142 { 2143 int rval; 2144 2145 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2146 2147 if (dop->length < ha->nvram_cache->size) { 2148 EL(ha, "failed, length=%xh, size=%xh\n", dop->length, 2149 ha->nvram_cache->size); 2150 return (EINVAL); 2151 } 2152 2153 if ((rval = ql_nv_util_dump(ha, (void *)(uintptr_t)dop->buffer, 2154 mode)) != 0) { 2155 EL(ha, "failed, ql_nv_util_dump\n"); 2156 } else { 2157 /*EMPTY*/ 2158 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2159 } 2160 2161 return (rval); 2162 } 2163 2164 /* 2165 * ql_adm_nvram_load 2166 * Performs qladm QL_NVRAM_LOAD command 2167 * 2168 * Input: 2169 * ha: adapter state pointer. 2170 * dop: ql_adm_op_t structure pointer. 2171 * mode: flags. 2172 * 2173 * Returns: 2174 * 2175 * Context: 2176 * Kernel context. 2177 */ 2178 static int 2179 ql_adm_nvram_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2180 { 2181 int rval; 2182 2183 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2184 2185 if (dop->length < ha->nvram_cache->size) { 2186 EL(ha, "failed, length=%xh, size=%xh\n", dop->length, 2187 ha->nvram_cache->size); 2188 return (EINVAL); 2189 } 2190 2191 if ((rval = ql_nv_util_load(ha, (void *)(uintptr_t)dop->buffer, 2192 mode)) != 0) { 2193 EL(ha, "failed, ql_nv_util_dump\n"); 2194 } else { 2195 /*EMPTY*/ 2196 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2197 } 2198 2199 return (rval); 2200 } 2201 2202 /* 2203 * ql_adm_flash_load 2204 * Performs qladm QL_FLASH_LOAD command 2205 * 2206 * Input: 2207 * ha: adapter state pointer. 2208 * dop: ql_adm_op_t structure pointer. 2209 * mode: flags. 2210 * 2211 * Returns: 2212 * 2213 * Context: 2214 * Kernel context. 2215 */ 2216 static int 2217 ql_adm_flash_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2218 { 2219 uint8_t *dp; 2220 int rval; 2221 2222 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2223 2224 if ((dp = kmem_zalloc(dop->length, KM_SLEEP)) == NULL) { 2225 EL(ha, "failed, kmem_zalloc\n"); 2226 return (ENOMEM); 2227 } 2228 2229 if (ddi_copyin((void *)(uintptr_t)dop->buffer, dp, dop->length, 2230 mode) != 0) { 2231 EL(ha, "ddi_copyin failed\n"); 2232 kmem_free(dp, dop->length); 2233 return (EFAULT); 2234 } 2235 2236 if (ql_stall_driver(ha, 0) != QL_SUCCESS) { 2237 EL(ha, "ql_stall_driver failed\n"); 2238 kmem_free(dp, dop->length); 2239 return (EBUSY); 2240 } 2241 2242 rval = (CFG_IST(ha, CFG_CTRL_24258081) ? 2243 ql_24xx_load_flash(ha, dp, dop->length, dop->option) : 2244 ql_load_flash(ha, dp, dop->length)); 2245 2246 ql_restart_driver(ha); 2247 2248 kmem_free(dp, dop->length); 2249 2250 if (rval != QL_SUCCESS) { 2251 EL(ha, "failed\n"); 2252 return (EIO); 2253 } 2254 2255 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2256 2257 return (0); 2258 } 2259 2260 /* 2261 * ql_adm_vpd_dump 2262 * Performs qladm QL_VPD_DUMP command 2263 * 2264 * Input: 2265 * ha: adapter state pointer. 2266 * dop: ql_adm_op_t structure pointer. 2267 * mode: flags. 2268 * 2269 * Returns: 2270 * 2271 * Context: 2272 * Kernel context. 2273 */ 2274 static int 2275 ql_adm_vpd_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2276 { 2277 int rval; 2278 2279 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2280 2281 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 2282 EL(ha, "hba does not support VPD\n"); 2283 return (EINVAL); 2284 } 2285 2286 if (dop->length < QL_24XX_VPD_SIZE) { 2287 EL(ha, "failed, length=%xh, size=%xh\n", dop->length, 2288 QL_24XX_VPD_SIZE); 2289 return (EINVAL); 2290 } 2291 2292 if ((rval = ql_vpd_dump(ha, (void *)(uintptr_t)dop->buffer, mode)) 2293 != 0) { 2294 EL(ha, "failed, ql_vpd_dump\n"); 2295 } else { 2296 /*EMPTY*/ 2297 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2298 } 2299 2300 return (rval); 2301 } 2302 2303 /* 2304 * ql_adm_vpd_load 2305 * Performs qladm QL_VPD_LOAD command 2306 * 2307 * Input: 2308 * ha: adapter state pointer. 2309 * dop: ql_adm_op_t structure pointer. 2310 * mode: flags. 2311 * 2312 * Returns: 2313 * 2314 * Context: 2315 * Kernel context. 2316 */ 2317 static int 2318 ql_adm_vpd_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2319 { 2320 int rval; 2321 2322 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2323 2324 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 2325 EL(ha, "hba does not support VPD\n"); 2326 return (EINVAL); 2327 } 2328 2329 if (dop->length < QL_24XX_VPD_SIZE) { 2330 EL(ha, "failed, length=%xh, size=%xh\n", dop->length, 2331 QL_24XX_VPD_SIZE); 2332 return (EINVAL); 2333 } 2334 2335 if ((rval = ql_vpd_load(ha, (void *)(uintptr_t)dop->buffer, mode)) 2336 != 0) { 2337 EL(ha, "failed, ql_vpd_dump\n"); 2338 } else { 2339 /*EMPTY*/ 2340 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2341 } 2342 2343 return (rval); 2344 } 2345 2346 /* 2347 * ql_adm_vpd_gettag 2348 * Performs qladm QL_VPD_GETTAG command 2349 * 2350 * Input: 2351 * ha: adapter state pointer. 2352 * dop: ql_adm_op_t structure pointer. 2353 * mode: flags. 2354 * 2355 * Returns: 2356 * 2357 * Context: 2358 * Kernel context. 2359 */ 2360 static int 2361 ql_adm_vpd_gettag(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2362 { 2363 int rval = 0; 2364 uint8_t *lbuf; 2365 2366 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2367 2368 if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) { 2369 EL(ha, "hba does not support VPD\n"); 2370 return (EINVAL); 2371 } 2372 2373 if ((lbuf = (uint8_t *)kmem_zalloc(dop->length, KM_SLEEP)) == NULL) { 2374 EL(ha, "mem alloc failure of %xh bytes\n", dop->length); 2375 rval = EFAULT; 2376 } else { 2377 if (ddi_copyin((void *)(uintptr_t)dop->buffer, lbuf, 2378 dop->length, mode) != 0) { 2379 EL(ha, "ddi_copyin failed\n"); 2380 kmem_free(lbuf, dop->length); 2381 return (EFAULT); 2382 } 2383 2384 if ((rval = ql_vpd_lookup(ha, lbuf, lbuf, (int32_t) 2385 dop->length)) < 0) { 2386 EL(ha, "failed vpd_lookup\n"); 2387 } else { 2388 if (ddi_copyout(lbuf, (void *)(uintptr_t)dop->buffer, 2389 strlen((int8_t *)lbuf)+1, mode) != 0) { 2390 EL(ha, "failed, ddi_copyout\n"); 2391 rval = EFAULT; 2392 } else { 2393 rval = 0; 2394 } 2395 } 2396 kmem_free(lbuf, dop->length); 2397 } 2398 2399 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2400 2401 return (rval); 2402 } 2403 2404 /* 2405 * ql_adm_updfwmodule 2406 * Performs qladm QL_UPD_FWMODULE command 2407 * 2408 * Input: 2409 * ha: adapter state pointer. 2410 * dop: ql_adm_op_t structure pointer. 2411 * mode: flags. 2412 * 2413 * Returns: 2414 * 2415 * Context: 2416 * Kernel context. 2417 */ 2418 /* ARGSUSED */ 2419 static int 2420 ql_adm_updfwmodule(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode) 2421 { 2422 int rval = DDI_SUCCESS; 2423 ql_link_t *link; 2424 ql_adapter_state_t *ha2 = NULL; 2425 uint16_t fw_class = (uint16_t)dop->option; 2426 2427 QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance); 2428 2429 /* zero the firmware module reference count */ 2430 for (link = ql_hba.first; link != NULL; link = link->next) { 2431 ha2 = link->base_address; 2432 if (fw_class == ha2->fw_class) { 2433 if ((rval = ddi_modclose(ha2->fw_module)) != 2434 DDI_SUCCESS) { 2435 EL(ha2, "modclose rval=%xh\n", rval); 2436 break; 2437 } 2438 ha2->fw_module = NULL; 2439 } 2440 } 2441 2442 /* reload the f/w modules */ 2443 for (link = ql_hba.first; link != NULL; link = link->next) { 2444 ha2 = link->base_address; 2445 2446 if ((fw_class == ha2->fw_class) && (ha2->fw_class == NULL)) { 2447 if ((rval = (int32_t)ql_fwmodule_resolve(ha2)) != 2448 QL_SUCCESS) { 2449 EL(ha2, "unable to load f/w module: '%x' " 2450 "(rval=%xh)\n", ha2->fw_class, rval); 2451 rval = EFAULT; 2452 } else { 2453 EL(ha2, "f/w module updated: '%x'\n", 2454 ha2->fw_class); 2455 } 2456 2457 EL(ha2, "isp abort needed (%d)\n", ha->instance); 2458 2459 ql_awaken_task_daemon(ha2, NULL, ISP_ABORT_NEEDED, 0); 2460 2461 rval = 0; 2462 } 2463 } 2464 2465 QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance); 2466 2467 return (rval); 2468 } 2469