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 2009 QLogic Corporation */ 23 24 /* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #pragma ident "Copyright 2009 QLogic Corporation; ql_hba_fru.c" 30 31 /* 32 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 33 * 34 * *********************************************************************** 35 * * ** 36 * * NOTICE ** 37 * * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION ** 38 * * ALL RIGHTS RESERVED ** 39 * * ** 40 * *********************************************************************** 41 * 42 */ 43 44 /* 45 * Determine HBA FRU card information for T11 FC-HBA 46 */ 47 48 #include <ql_apps.h> 49 #include <ql_api.h> 50 #include <ql_debug.h> 51 #include <ql_ioctl.h> 52 #include <ql_xioctl.h> 53 54 /* 55 * Temporary define until LV headers are updated 56 */ 57 #ifndef FC_HBA_PORTSPEED_8GBIT 58 #define FC_HBA_PORTSPEED_8GBIT 16 /* 8 GBit/sec */ 59 #endif 60 61 /* Local prototypes */ 62 static uint32_t ql_get_basedev_len(ql_adapter_state_t *, uint32_t *, 63 uint32_t *); 64 static ql_adapter_state_t *ql_search_basedev(ql_adapter_state_t *, uint32_t); 65 66 /* Local structures */ 67 static struct ql_known_models { 68 uint16_t ssid; /* Subsystem ID */ 69 uint16_t ssvid; /* Subsystem Vendor ID */ 70 char model[256]; 71 char model_description[256]; 72 73 } models[] = { 74 { 75 /* QLogic */ 76 0x2, 0x1077, "QLA2200", "QLogic PCI to 1Gb FC, Single Channel" 77 }, { 78 /* QLogic */ 79 0x9, 0x1077, "QLA2300", "QLogic PCI to 2Gb FC, Single Channel" 80 }, { 81 /* QLA2200, SUN2200 Amber */ 82 0x4082, 0x1077, "375-3019-xx", "X6799A" 83 }, { 84 /* QLA2212, SUN2212 Crystal+ */ 85 0x4083, 0x1077, "375-3030-xx", "X6727A" 86 }, { 87 /* QCP2202, SUNQCP2202 Diamond */ 88 0x4084, 0x1077, "375-0118-xx", "X6748A" 89 }, { 90 /* QLA2202FS, SUN2202FS Ivory */ 91 0x4085, 0x1077, "375-3048-xx", "X6757A" 92 }, { 93 /* QLogic */ 94 0x100, 0x1077, "QLA2340", 95 "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 96 }, { 97 /* QLogic */ 98 0x101, 0x1077, "QLA2342", 99 "QLogic 133MHz PCI-X to 2Gb FC, Dual Channel" 100 }, { 101 /* QLogic */ 102 0x102, 0x1077, "QLA2344", 103 "QLogic 133MHz PCI-X to 2Gb FC, Quad Channel" 104 }, { 105 /* QLogic */ 106 0x103, 0x1077, "QCP2342", "QLogic cPCI to 2Gb FC, Dual Channel" 107 }, { 108 /* QLogic */ 109 0x104, 0x1077, "QSB2340", "QLogic SBUS to 2Gb FC, Single Channel" 110 }, { 111 /* QLogic */ 112 0x105, 0x1077, "QSB2342", "QLogic SBUS to 2Gb FC, Dual Channel" 113 }, { 114 /* QLA2310, SUN-66MHz PCI-X to 2Gb FC, Single Channel, Amber 2 */ 115 0x0106, 0x1077, "375-3102-xx", "SG-XPCI1FC-QF2 (X6767A)" 116 }, { 117 /* QLogic */ 118 0x109, 0x1077, "QCP2340", "QLogic cPCI to 2Gb FC, Single Channel" 119 }, { 120 /* QLA2342, SUN-133MHz PCI-X to 2Gb FC, Dualchannel, Crystal 2A */ 121 0x010A, 0x1077, "375-3108-xx", "SG-XPCI2FC-QF2 (X6768A)" 122 }, { 123 /* QLogic */ 124 0x115, 0x1077, "QLA2360", 125 "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 126 }, { 127 /* QLogic */ 128 0x116, 0x1077, "QLA2362", 129 "QLogic 133MHz PCI-X to 2Gb FC, Dual Channel" 130 }, { 131 /* QLogic */ 132 0x117, 0x1077, "QLE2360", 133 "QLogic PCI-Express to 2Gb FC, Single Channel" 134 }, { 135 /* QLogic */ 136 0x118, 0x1077, "QLE2362", 137 "QLogic PCI Express to 2Gb FC, Dual Channel" 138 }, { 139 /* QLogic */ 140 0x119, 0x1077, "QLA200", 141 "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 142 }, { 143 /* QLogic */ 144 0x11c, 0x1077, "QLA200P", 145 "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 146 }, { 147 /* QLogic */ 148 0x12f, 0x1077, "QLA210", 149 "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 150 }, { 151 /* QLogic */ 152 0x130, 0x1077, "EMC250-051-900", 153 "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 154 }, { 155 /* QLA210, SUN-133MHz PCI-X to 2Gb FC, Single Channel, Prism */ 156 0x132, 0x1077, "375-32X3-01", "SG-PCI1FC-QLC" 157 }, { 158 /* QLogic */ 159 0x13e, 0x1077, "QLE210", 160 "QLogic PCI Express 2Gb FC, Single Channel" 161 }, { 162 /* Sun */ 163 0x149, 0x1077, "QLA2340", 164 "SUN - 133MHz PCI-X to 2Gb FC, Single Channel" 165 }, { 166 /* HP */ 167 0x100, 0x0e11, "QLA2340-HP", "PCIX to 2Gb FC, Single Channel" 168 }, { 169 /* HP */ 170 0x101, 0x0e11, "QLA2342-HP", "PCIX to 2Gb FC, Dual Channel" 171 }, { 172 /* HP */ 173 0x103, 0x0e11, "QLA2312-HP", 174 "HP Bladed Server Balcony Card - HP BalcnL" 175 }, { 176 /* HP */ 177 0x104, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP MezzF" 178 }, { 179 /* HP */ 180 0x105, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP BalcnL" 181 }, { 182 /* HP */ 183 0x106, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP BalcnF" 184 }, { 185 /* HP */ 186 0x107, 0x0e11, "QLA2312-HP", "HP Bladed Server" 187 }, { 188 /* HP */ 189 0x108, 0x0e11, "QLA2312-HP", "HP Bladed Server" 190 }, { 191 /* IBM FCEC */ 192 0x27d, 0x1014, "IBM-FCEC", 193 "IBM eServer Blade Center FC Expansion Card" 194 }, { 195 /* IBM FCEC */ 196 0x2fb, 0x1014, "IBM-FCEC", 197 "IBM eServer Blade Center FC SFF Expansion Card" 198 }, { 199 /* Intel */ 200 0x34ba, 0x8086, "Intel SBFCM", 201 "Intel Server FC Expansion Card SBFCM" 202 }, { 203 /* Intel */ 204 0x34a0, 0x8086, "Intel SBEFCM", 205 "Intel Server SFF FC Expansion Card SBFCM" 206 }, { 207 /* FCI/O */ 208 0x1051, 0x1734, "FCI/O-CARD2Gb/s", 209 "FSC-Quanta FC I/O-Card 2GBit/s" 210 }, { 211 /* Dell */ 212 0x18a, 0x1028, "FCI/O-CARD2Gb/s", "Dell Glacier Blade Server" 213 }, { 214 /* end of list */ 215 0, 0, 0, 0, 0, 0 216 } }; 217 218 /* 219 * ql_populate_hba_fru_details 220 * Sets up HBA fru information for UL utilities 221 * (cfgadm, fcinfo, et. al.) 222 * 223 * Input: 224 * ha = adapter state structure 225 * port_info = ptr to LV port strcture. 226 * 227 * Returns: 228 * 229 * Context: 230 * Kernel context. 231 */ 232 void 233 ql_populate_hba_fru_details(ql_adapter_state_t *ha, 234 fc_fca_port_info_t *port_info) 235 { 236 fca_port_attrs_t *attrs = &port_info->pi_attrs; 237 uint16_t chip = ha->device_id; 238 uint16_t model = ha->subsys_id; 239 uint16_t ssdevid = ha->subven_id; 240 size_t vlen; 241 int32_t i; 242 243 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 244 245 attrs = &port_info->pi_attrs; 246 247 /* Constants */ 248 (void) snprintf(attrs->manufacturer, FCHBA_MANUFACTURER_LEN, 249 "QLogic Corp."); 250 (void) snprintf(attrs->driver_name, FCHBA_DRIVER_NAME_LEN, 251 "%s", QL_NAME); 252 (void) snprintf(attrs->driver_version, FCHBA_DRIVER_VERSION_LEN, 253 "%s", ha->adapter_stats->revlvl.qlddv); 254 255 if ((i = ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_SN, (uint8_t *) 256 attrs->serial_number, FCHBA_SERIAL_NUMBER_LEN)) == -1) { 257 attrs->serial_number[0] = '\0'; 258 } 259 attrs->hardware_version[0] = '\0'; 260 261 /* Dynamic data */ 262 (void) snprintf(attrs->firmware_version, FCHBA_FIRMWARE_VERSION_LEN, 263 "%02d.%02d.%02d", ha->fw_major_version, ha->fw_minor_version, 264 ha->fw_subminor_version); 265 266 CACHE_LOCK(ha); 267 268 /* Report FCode / BIOS / EFI version(s). */ 269 if (ha->fcache != NULL) { 270 uint32_t types = FTYPE_BIOS|FTYPE_FCODE|FTYPE_EFI; 271 ql_fcache_t *fptr = ha->fcache; 272 int8_t *orv = &*attrs->option_rom_version; 273 274 while ((fptr != NULL) && (types != 0)) { 275 /* Get the next image */ 276 if ((fptr = ql_get_fbuf(ha->fcache, types)) != NULL) { 277 278 switch (fptr->type) { 279 case FTYPE_FCODE: 280 (void) snprintf(orv, 281 FCHBA_OPTION_ROM_VERSION_LEN, 282 "%s fcode: %s;", orv, fptr->verstr); 283 break; 284 case FTYPE_BIOS: 285 (void) snprintf(orv, 286 FCHBA_OPTION_ROM_VERSION_LEN, 287 "%s BIOS: %s;", orv, fptr->verstr); 288 break; 289 case FTYPE_EFI: 290 (void) snprintf(orv, 291 FCHBA_OPTION_ROM_VERSION_LEN, 292 "%s EFI: %s;", orv, fptr->verstr); 293 break; 294 default: 295 EL(ha, "ignoring ftype: %xh\n", 296 fptr->type); 297 break; 298 } 299 types &= ~(fptr->type); 300 } 301 } 302 } 303 304 CACHE_UNLOCK(ha); 305 306 if (strlen(attrs->option_rom_version) == 0) { 307 int rval = -1; 308 uint32_t i = 0; 309 caddr_t fcode_ver_buf = NULL; 310 311 if (CFG_IST(ha, CFG_CTRL_2200)) { 312 /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 313 rval = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip, 314 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version", 315 (caddr_t)&fcode_ver_buf, (int32_t *)&i); 316 } 317 318 (void) snprintf(attrs->option_rom_version, 319 FCHBA_OPTION_ROM_VERSION_LEN, "%s", 320 (rval == DDI_PROP_SUCCESS ? fcode_ver_buf : 321 "No boot image detected")); 322 323 if (fcode_ver_buf != NULL) { 324 kmem_free(fcode_ver_buf, (size_t)i); 325 } 326 327 } 328 329 attrs->vendor_specific_id = ha->adapter_features; 330 attrs->max_frame_size = CFG_IST(ha, CFG_CTRL_242581) ? 331 (ha->init_ctrl_blk.cb24.max_frame_length[1] << 8 | 332 ha->init_ctrl_blk.cb24.max_frame_length[0]) : 333 (ha->init_ctrl_blk.cb.max_frame_length[1] << 8 | 334 ha->init_ctrl_blk.cb.max_frame_length[0]); 335 attrs->supported_cos = 0x10000000; /* Class 3 only */ 336 337 switch (chip & 0xFF00) { 338 case 0x2200: 339 attrs->supported_speed = FC_HBA_PORTSPEED_1GBIT; 340 break; 341 case 0x2300: 342 attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT | 343 FC_HBA_PORTSPEED_1GBIT; 344 break; 345 case 0x2400: 346 case 0x8400: 347 attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT | 348 FC_HBA_PORTSPEED_2GBIT | FC_HBA_PORTSPEED_1GBIT; 349 break; 350 case 0x8000: 351 attrs->supported_speed = FC_HBA_PORTSPEED_10GBIT; 352 break; 353 case 0x2500: 354 attrs->supported_speed = FC_HBA_PORTSPEED_8GBIT | 355 FC_HBA_PORTSPEED_4GBIT | FC_HBA_PORTSPEED_2GBIT | 356 FC_HBA_PORTSPEED_1GBIT; 357 358 /* 359 * Correct supported speeds based on type of 360 * sfp that is present 361 */ 362 switch (ha->sfp_stat) { 363 case 2: 364 case 4: 365 /* 4GB sfp */ 366 attrs->supported_speed &= ~FC_HBA_PORTSPEED_8GBIT; 367 break; 368 case 3: 369 case 5: 370 /* 8GB sfp */ 371 attrs->supported_speed &= ~FC_HBA_PORTSPEED_1GBIT; 372 break; 373 default: 374 EL(ha, "sfp_stat: %xh\n", ha->sfp_stat); 375 break; 376 377 } 378 379 break; 380 case 0x5400: 381 if (model == 0x13e) { 382 /* QLE210 */ 383 attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT; 384 } else { 385 attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT; 386 } 387 break; 388 case 0x6300: 389 attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT; 390 break; 391 default: 392 attrs->supported_speed = FC_HBA_PORTSPEED_UNKNOWN; 393 break; 394 } 395 396 /* Use parent dip as adapter identifier */ 397 attrs->hba_fru_details.low = 0x514C6F6769630000; /* QLogic */ 398 399 if (ha->fru_hba_index == 0) { 400 EL(ha, "unable to generate high_fru details from " 401 "device path: %s\n", ha->devpath); 402 attrs->hba_fru_details.low = 0; 403 attrs->hba_fru_details.high = 0; 404 attrs->hba_fru_details.port_index = 0; 405 } else { 406 attrs->hba_fru_details.high = ha->fru_hba_index; 407 attrs->hba_fru_details.port_index = ha->fru_port_index; 408 } 409 410 /* 411 * Populate the model info. Legacy (22xx, 23xx, 63xx) do not 412 * have vpd info, so use the hard coded table. Anything else 413 * has VPD (or is suppose to have VPD), so use that. For both 414 * cases, if the model isn't found, use defaults. 415 */ 416 417 switch (chip & 0xFF00) { 418 case 0x2200: 419 case 0x2300: 420 case 0x6300: 421 /* Table based data */ 422 for (i = 0; models[i].ssid; i++) { 423 if ((model == models[i].ssid) && 424 (ssdevid == models[i].ssvid)) { 425 break; 426 } 427 } 428 429 if (models[i].ssid) { 430 (void) snprintf(attrs->model, FCHBA_MODEL_LEN, "%s", 431 models[i].model); 432 (void) snprintf(attrs->model_description, 433 FCHBA_MODEL_DESCRIPTION_LEN, "%s", 434 models[i].model_description); 435 } else { 436 (void) snprintf(attrs->model, FCHBA_MODEL_LEN, 437 "%x", chip); 438 (void) snprintf(attrs->model_description, 439 FCHBA_MODEL_DESCRIPTION_LEN, "%x", chip); 440 } 441 442 /* Special model handling for RoHS version of the HBA */ 443 if (models[i].ssid == 0x10a && ha->adapInfo[10] == 444 (uint8_t)0x36) { 445 (void) snprintf(attrs->model, FCHBA_MODEL_LEN, "%s", 446 "375-3363-xx"); 447 (void) snprintf(attrs->model_description, 448 FCHBA_MODEL_DESCRIPTION_LEN, "%s", 449 "SG-XPCI2FC-QF2-Z"); 450 } 451 break; 452 453 case 0x2400: 454 case 0x2500: 455 case 0x5400: 456 case 0x8400: 457 case 0x8000: 458 default: 459 if ((i = ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_PN, 460 (uint8_t *)attrs->model, FCHBA_MODEL_LEN)) >= 0) { 461 (void) ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_PRODID, 462 (uint8_t *)attrs->model_description, 463 FCHBA_MODEL_DESCRIPTION_LEN); 464 } else { 465 (void) snprintf(attrs->model, FCHBA_MODEL_LEN, 466 "%x", chip); 467 (void) snprintf(attrs->model_description, 468 FCHBA_MODEL_DESCRIPTION_LEN, "%x", chip); 469 } 470 break; 471 } 472 473 /* 474 * Populate the LV symbolic node and port name strings 475 * 476 * Symbolic node name format is: 477 * <hostname> 478 * 479 * Symbolic port name format is: 480 * <driver_name>(<instance>,<vp index>) 481 */ 482 vlen = (strlen(utsname.nodename) > FCHBA_SYMB_NAME_LEN ? 483 FCHBA_SYMB_NAME_LEN : strlen(utsname.nodename)); 484 (void) snprintf((int8_t *)attrs->sym_node_name, vlen, "%s", 485 utsname.nodename); 486 487 vlen = (strlen(QL_NAME) + 9 > FCHBA_SYMB_NAME_LEN ? 488 FCHBA_SYMB_NAME_LEN : strlen(QL_NAME) + 9); 489 (void) snprintf((int8_t *)attrs->sym_port_name, vlen, 490 "%s(%d,%d)", QL_NAME, ha->instance, ha->vp_index); 491 492 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 493 } 494 495 /* 496 * ql_setup_fruinfo 497 * Generates common id's for instances on the same 498 * physical HBA. 499 * 500 * Input: 501 * ha = adapter state structure 502 * 503 * Returns: 504 * 505 * Context: 506 * Kernel context. 507 */ 508 void 509 ql_setup_fruinfo(ql_adapter_state_t *ha) 510 { 511 uint32_t mybasedev_len; 512 ql_adapter_state_t *base_ha = NULL; 513 514 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 515 516 /* 517 * To generate common id for instances residing on the 518 * the same HBA, the devpath for each instance is parsed 519 * and those instances which have matching base devpaths are 520 * given same hba_index, and each port on the same hba are 521 * then assigned unique port_indexs based on the devpath. 522 */ 523 524 /* 525 * Get this ha's basedev path and its port index 526 */ 527 if (ql_get_basedev_len(ha, &mybasedev_len, &ha->fru_port_index) == 0) { 528 529 GLOBAL_STATE_LOCK(); 530 531 /* 532 * Search for this basedev against all of the 533 * ha in the ql_hba global list. If found one 534 * then we are part of other adapter in the 535 * ql_hba list and hence use that ha's hba_index. 536 * If not create a new one from the global hba index. 537 */ 538 base_ha = ql_search_basedev(ha, mybasedev_len); 539 if (base_ha != NULL && base_ha->fru_hba_index != 0) { 540 ha->fru_hba_index = base_ha->fru_hba_index; 541 } else { 542 ha->fru_hba_index = ql_gfru_hba_index++; 543 } 544 545 if (CFG_IST(ha, CFG_CTRL_81XX)) { 546 /* 547 * The FC functions on 81xx hbas are functions 2 and 3 548 * while the Nic functions occupy 0 and 1. Adjust 549 * fru port index to be like previous FCAs. 550 */ 551 ha->fru_port_index -= 2; 552 } 553 554 GLOBAL_STATE_UNLOCK(); 555 556 } else { 557 ha->fru_hba_index = 0; 558 ha->fru_port_index = 0; 559 } 560 561 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 562 } 563 564 /* 565 * ql_get_basedev_len 566 * 567 * Gets the length of the base device name in the 568 * devpath of the current instance. 569 * 570 * Input: 571 * ha - adapter state pointer. 572 * basedev_len - pointer to the integer which 573 * holds the calculated length. 574 * port_index - pointer to the integer which 575 * contains the port index of 576 * for this device. 577 * Returns: 578 * 0 if successfully parsed, -1 otherwise. 579 * 580 * Context: 581 * Kernel context. 582 */ 583 static uint32_t 584 ql_get_basedev_len(ql_adapter_state_t *ha, uint32_t *basedev_len, 585 uint32_t *port_index) 586 { 587 int32_t dev_off; 588 int32_t port_off; 589 int8_t *devstr; 590 591 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 592 593 if (ha->devpath == NULL) { 594 return ((uint32_t)-1); 595 } 596 597 dev_off = (int32_t)(strlen(ha->devpath) - 1); 598 port_off = -1; 599 600 /* Until we reach the first char or a '@' char in the path */ 601 while ((dev_off >= 0) && (ha->devpath[dev_off] != '@')) { 602 603 if (ha->devpath[dev_off] == ',') { 604 port_off = dev_off + 1; 605 } 606 607 dev_off--; 608 } 609 610 if (dev_off < 0) { 611 EL(ha, "Invalid device path '%s'. Cannot get basedev\n", 612 ha->devpath); 613 return ((uint32_t)-1); 614 } 615 616 if (port_off == -1) { 617 *port_index = 0; 618 *basedev_len = (uint32_t)strlen(ha->devpath); 619 } else { 620 /* Get the port index */ 621 devstr = ha->devpath + port_off; 622 *port_index = stoi(&devstr); 623 if (*port_index == 0) { 624 EL(ha, "Invalid device path '%s'. Cannot get " 625 "port_index\n", ha->devpath); 626 return ((uint32_t)-1); 627 } 628 629 *basedev_len = (uint32_t)(port_off - 1); 630 } 631 632 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 633 634 return (0); 635 } 636 637 /* 638 * ql_search_basedev 639 * Searches the list of ha instances to find which 640 * ha instance has same base device path as input's. 641 * 642 * Input: 643 * myha = current adapter state pointer. 644 * mybasedev_len = Length of the base device in the 645 * device path name. 646 * 647 * Returns: 648 * If match = ptr to matching ha structure. 649 * If no match = NULL ptr. 650 * 651 * Context: 652 * Kernel context. 653 */ 654 static ql_adapter_state_t * 655 ql_search_basedev(ql_adapter_state_t *myha, uint32_t mybasedev_len) 656 { 657 ql_link_t *link; 658 ql_adapter_state_t *ha; 659 uint32_t basedev_len, port_index; 660 661 QL_PRINT_3(CE_CONT, "(%d): started\n", myha->instance); 662 663 for (link = ql_hba.first; link != NULL; link = link->next) { 664 665 ha = link->base_address; 666 667 if (ha == NULL) { 668 EL(myha, "null ha link detected!\n"); 669 return (NULL); 670 } 671 672 if (ha == myha) { 673 continue; 674 } 675 676 if (ql_get_basedev_len(ha, &basedev_len, &port_index) != 0) { 677 if (ha->devpath == NULL) { 678 EL(myha, "Device path NULL. Unable to get " 679 "the basedev\n"); 680 } else { 681 EL(myha, "Invalid device path '%s'. Cannot " 682 "get the hba index and port index\n", 683 ha->devpath); 684 } 685 continue; 686 } 687 688 /* 689 * If both the basedev len do not match, then it 690 * is obvious that both are not pointing to the 691 * same base device. 692 */ 693 if ((basedev_len == mybasedev_len) && (strncmp(myha->devpath, 694 ha->devpath, basedev_len) == 0)) { 695 696 /* We found the ha with same basedev */ 697 QL_PRINT_3(CE_CONT, "(%d): found, done\n", 698 myha->instance); 699 return (ha); 700 } 701 } 702 703 QL_PRINT_3(CE_CONT, "(%d): not found, done\n", myha->instance); 704 705 return (NULL); 706 } 707