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