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