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
 
 
 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
 
 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 }
 | 
 
 
   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 2015 QLogic Corporation */
  23 
  24 /*
  25  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  26  */
  27 
  28 #pragma ident   "Copyright 2015 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-2015 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
 
 
 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(ha, "started\n");
 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         /* 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         if (strlen(attrs->option_rom_version) == 0) {
 302                 int             rval = -1;
 303                 uint32_t        i = 0;
 304                 caddr_t         fcode_ver_buf = NULL;
 305 
 306                 if (CFG_IST(ha, CFG_CTRL_22XX)) {
 307                         /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
 308                         rval = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip,
 309                             DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version",
 310                             (caddr_t)&fcode_ver_buf, (int32_t *)&i);
 311                 }
 312 
 313                 (void) snprintf(attrs->option_rom_version,
 314                     FCHBA_OPTION_ROM_VERSION_LEN, "%s",
 315                     (rval == DDI_PROP_SUCCESS ? fcode_ver_buf :
 316                     "No boot image detected"));
 317 
 318                 if (fcode_ver_buf != NULL) {
 319                         kmem_free(fcode_ver_buf, (size_t)i);
 320                 }
 321 
 322         }
 323 
 324         attrs->vendor_specific_id = ha->adapter_features;
 325         attrs->max_frame_size = ha->loginparams.common_service.rx_bufsize;
 326         attrs->supported_cos = 0x10000000; /* Class 3 only */
 327 
 328         switch (chip & 0xFF00) {
 329         case 0x2000:
 330                 attrs->supported_speed = chip == 0x2071 ?
 331                     FC_HBA_PORTSPEED_32GBIT : FC_HBA_PORTSPEED_16GBIT;
 332                 break;
 333         case 0x2200:
 334                 attrs->supported_speed = chip == 0x2261 ?
 335                     FC_HBA_PORTSPEED_16GBIT : FC_HBA_PORTSPEED_1GBIT;
 336                 break;
 337         case 0x2300:
 338                 attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT |
 339                     FC_HBA_PORTSPEED_1GBIT;
 340                 break;
 341         case 0x2400:
 342         case 0x8400:
 343                 attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT |
 344                     FC_HBA_PORTSPEED_2GBIT | FC_HBA_PORTSPEED_1GBIT;
 345                 break;
 346         case 0x8000:
 347                 attrs->supported_speed = FC_HBA_PORTSPEED_10GBIT;
 348                 break;
 349         case 0x2500:
 350                 attrs->supported_speed = FC_HBA_PORTSPEED_8GBIT |
 351                     FC_HBA_PORTSPEED_4GBIT | FC_HBA_PORTSPEED_2GBIT |
 352                     FC_HBA_PORTSPEED_1GBIT;
 353 
 354                 /*
 355                  * Correct supported speeds based on type of
 
 468 
 469         /*
 470          * Populate the LV symbolic node and port name strings
 471          *
 472          * Symbolic node name format is:
 473          *      <hostname>
 474          *
 475          * Symbolic port name format is:
 476          *      <driver_name>(<instance>,<vp index>)
 477          */
 478         vlen = (strlen(utsname.nodename) > FCHBA_SYMB_NAME_LEN ?
 479             FCHBA_SYMB_NAME_LEN : strlen(utsname.nodename));
 480         (void) snprintf((int8_t *)attrs->sym_node_name, vlen, "%s",
 481             utsname.nodename);
 482 
 483         vlen = (strlen(QL_NAME) + 9 > FCHBA_SYMB_NAME_LEN ?
 484             FCHBA_SYMB_NAME_LEN : strlen(QL_NAME) + 9);
 485         (void) snprintf((int8_t *)attrs->sym_port_name, vlen,
 486             "%s(%d,%d)", QL_NAME, ha->instance, ha->vp_index);
 487 
 488         QL_PRINT_3(ha, "done\n");
 489 }
 490 
 491 /*
 492  * ql_setup_fruinfo
 493  *      Generates common id's for instances on the same
 494  *      physical HBA.
 495  *
 496  * Input:
 497  *      ha =  adapter state structure
 498  *
 499  * Returns:
 500  *
 501  * Context:
 502  *      Kernel context.
 503  */
 504 void
 505 ql_setup_fruinfo(ql_adapter_state_t *ha)
 506 {
 507         uint32_t                mybasedev_len;
 508         ql_adapter_state_t      *base_ha = NULL;
 509 
 510         QL_PRINT_3(ha, "started\n");
 511 
 512         /*
 513          * To generate common id for instances residing on the
 514          * the same HBA, the devpath for each instance is parsed
 515          * and those instances which have matching base devpaths are
 516          * given same hba_index, and each port on the same hba are
 517          * then assigned unique port_indexs based on the devpath.
 518          */
 519 
 520         /*
 521          * Get this ha's basedev path and its port index
 522          */
 523         if (ql_get_basedev_len(ha, &mybasedev_len, &ha->fru_port_index) == 0) {
 524 
 525                 /*
 526                  * Search for this basedev against all of the
 527                  * ha in the ql_hba global list. If found one
 528                  * then we are part of other adapter in the
 529                  * ql_hba list and hence use that ha's hba_index.
 530                  * If not create a new one from the global hba index.
 531                  */
 532                 base_ha = ql_search_basedev(ha, mybasedev_len);
 533                 if (base_ha != NULL && base_ha->fru_hba_index != 0) {
 534                         ha->fru_hba_index = base_ha->fru_hba_index;
 535                         ha->fru_port_index = base_ha->fru_port_index + 1;
 536                 } else {
 537                         ha->fru_hba_index = ql_gfru_hba_index++;
 538                         ha->fru_port_index = 0;
 539                 }
 540         } else {
 541                 ha->fru_hba_index = 0;
 542                 ha->fru_port_index = 0;
 543         }
 544 
 545         QL_PRINT_3(ha, "done\n");
 546 }
 547 
 548 /*
 549  *  ql_get_basedev_len
 550  *
 551  *      Gets the length of the base device name in the
 552  *      devpath of the current instance.
 553  *
 554  * Input:
 555  *      ha              - adapter state pointer.
 556  *      basedev_len     - pointer to the integer which
 557  *                        holds the calculated length.
 558  *      port_index      - pointer to the integer which
 559  *                        contains the port index of
 560  *                        for this device.
 561  * Returns:
 562  *      0 if successfully parsed, -1 otherwise.
 563  *
 564  * Context:
 565  *      Kernel context.
 566  */
 567 static uint32_t
 568 ql_get_basedev_len(ql_adapter_state_t *ha, uint32_t *basedev_len,
 569     uint32_t *port_index)
 570 {
 571         int32_t         dev_off;
 572         int32_t         port_off;
 573         int8_t          *devstr;
 574 
 575         QL_PRINT_3(ha, "started\n");
 576 
 577         if (ha->devpath == NULL) {
 578                 return ((uint32_t)-1);
 579         }
 580 
 581         dev_off = (int32_t)(strlen(ha->devpath) - 1);
 582         port_off = -1;
 583 
 584         /* Until we reach the first char or a '@' char in the path */
 585         while ((dev_off >= 0) && (ha->devpath[dev_off] != '@')) {
 586 
 587                 if (ha->devpath[dev_off] == ',') {
 588                         port_off = dev_off + 1;
 589                 }
 590 
 591                 dev_off--;
 592         }
 593 
 594         if (dev_off < 0) {
 595                 EL(ha, "Invalid device path '%s'. Cannot get basedev\n",
 596                     ha->devpath);
 597                 return ((uint32_t)-1);
 598         }
 599 
 600         if (port_off == -1) {
 601                 *port_index = 0;
 602                 *basedev_len = (uint32_t)strlen(ha->devpath);
 603         } else {
 604                 /* Get the port index */
 605                 devstr = ha->devpath + port_off;
 606                 *port_index = stoi(&devstr);
 607                 if (*port_index == 0) {
 608                         EL(ha, "Invalid device path '%s'. Cannot get "
 609                             "port_index\n", ha->devpath);
 610                         return ((uint32_t)-1);
 611                 }
 612 
 613                 *basedev_len = (uint32_t)(port_off - 1);
 614         }
 615 
 616         QL_PRINT_3(ha, "done\n");
 617 
 618         return (0);
 619 }
 620 
 621 /*
 622  * ql_search_basedev
 623  *      Searches the list of ha instances to find which
 624  *      ha instance has same base device path as input's.
 625  *
 626  * Input:
 627  *      myha            = current adapter state pointer.
 628  *      mybasedev_len   = Length of the base device in the
 629  *                        device path name.
 630  *
 631  * Returns:
 632  *      If match        = ptr to matching ha structure.
 633  *      If no match     = NULL ptr.
 634  *
 635  * Context:
 636  *      Kernel context.
 637  */
 638 static ql_adapter_state_t *
 639 ql_search_basedev(ql_adapter_state_t *myha, uint32_t mybasedev_len)
 640 {
 641         ql_link_t               *link;
 642         ql_adapter_state_t      *ha;
 643         uint32_t                basedev_len, port_index;
 644 
 645         QL_PRINT_3(myha, "started\n", myha->instance);
 646 
 647         for (link = ql_hba.first; link != NULL; link = link->next) {
 648 
 649                 ha = link->base_address;
 650 
 651                 if (ha == NULL) {
 652                         EL(myha, "null ha link detected!\n");
 653                         return (NULL);
 654                 }
 655 
 656                 if (ha == myha) {
 657                         continue;
 658                 }
 659 
 660                 if (ql_get_basedev_len(ha, &basedev_len, &port_index) != 0) {
 661                         if (ha->devpath == NULL) {
 662                                 EL(myha, "Device path NULL. Unable to get "
 663                                     "the basedev\n");
 664                         } else {
 665                                 EL(myha, "Invalid device path '%s'. Cannot "
 666                                     "get the hba index and port index\n",
 667                                     ha->devpath);
 668                         }
 669                         continue;
 670                 }
 671 
 672                 /*
 673                  * If both the basedev len do not match, then it
 674                  * is obvious that both are not pointing to the
 675                  * same base device.
 676                  */
 677                 if ((basedev_len == mybasedev_len) && (strncmp(myha->devpath,
 678                     ha->devpath, basedev_len) == 0)) {
 679 
 680                         /* We found the ha with same basedev */
 681                         QL_PRINT_3(myha, "found, done\n",
 682                             myha->instance);
 683                         return (ha);
 684                 }
 685         }
 686 
 687         QL_PRINT_3(myha, "not found, done\n", myha->instance);
 688 
 689         return (NULL);
 690 }
 |