Print this page
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/fibre-channel/fca/qlc/ql_debug.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/qlc/ql_debug.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22      -/* Copyright 2009 QLogic Corporation */
       22 +/* Copyright 2015 QLogic Corporation */
  23   23  
  24   24  /*
  25      - * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  26      - * Use is subject to license terms.
       25 + * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
  27   26   */
  28   27  
  29      -#pragma ident   "Copyright 2009 QLogic Corporation; ql_debug.c"
       28 +#pragma ident   "Copyright 2015 QLogic Corporation; ql_debug.c"
  30   29  
  31   30  /*
  32   31   * Qlogic ISP22xx/ISP23xx/ISP24xx FCA driver source
  33   32   *
  34   33   * ***********************************************************************
  35   34   * *                                                                    **
  36   35   * *                            NOTICE                                  **
  37      - * *            COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION              **
       36 + * *            COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION              **
  38   37   * *                    ALL RIGHTS RESERVED                             **
  39   38   * *                                                                    **
  40   39   * ***********************************************************************
  41   40   *
  42   41   */
  43   42  
  44   43  #include <ql_apps.h>
  45   44  #include <ql_api.h>
  46   45  #include <ql_debug.h>
  47   46  
  48   47  static int ql_flash_errlog_store(ql_adapter_state_t *, uint32_t *);
  49      -int ql_validate_trace_desc(ql_adapter_state_t *ha);
  50      -char *ql_find_trace_start(ql_adapter_state_t *ha);
  51   48  
  52   49  /*
  53   50   * Global Data.
  54   51   */
  55   52  uint32_t        el_message_number = 0;
  56   53  uint32_t        ql_enable_ellock = 0;
  57   54  
  58      -extern int      getpcstack(pc_t *, int);
       55 +extern int      getpcstack(pc_t *, int);
  59   56  extern char     *kobj_getsymname(uintptr_t, ulong_t *);
  60   57  
  61   58  /*
  62   59   * ql_dump_buffer
  63   60   *       Outputs buffer.
  64   61   *
  65   62   * Input:
  66   63   *       string:        Null terminated string (no newline at end).
  67   64   *       buffer:        buffer address.
  68   65   *       wd_size:       word size 8 bits
↓ open down ↓ 70 lines elided ↑ open up ↑
 139  136   *      fn:     function name.
 140  137   *      ce:     level
 141  138   *      ...:    Variable argument list.
 142  139   *
 143  140   * Context:
 144  141   *      Kernel/Interrupt context.
 145  142   */
 146  143  void
 147  144  ql_el_msg(ql_adapter_state_t *ha, const char *fn, int ce, ...)
 148  145  {
 149      -        uint32_t        el_msg_num;
 150      -        char            *s, *fmt = 0, *fmt1 = 0;
 151      -        char            fmt2[256];
 152      -        int             rval, tmp;
 153      -        int             tracing = 0;
 154      -        va_list         vl;
      146 +        char            *s, *fmt, *fmt1;
      147 +        /*
      148 +         * EL_BUFFER_RESERVE 256 is the max # of bytes
      149 +         * that driver's log could be collected.
      150 +         * add 3 more buytes for safely maniplulation.
      151 +         */
      152 +        char                    buf[EL_BUFFER_RESERVE + 3];
      153 +        char                    buf1[QL_LOG_LENGTH];
      154 +        size_t                  tmp, rval, rval1, left;
      155 +        va_list                 vl;
      156 +        ql_trace_desc_t         *desc;
      157 +        ql_trace_entry_t        *entry;
      158 +        uint32_t                cindex, count;
      159 +        timespec_t              time;
 155  160  
 156      -        /* Tracing is the default but it can be disabled. */
 157      -        if ((CFG_IST(ha, CFG_DISABLE_EXTENDED_LOGGING_TRACE) == 0) &&
 158      -            (rval = ql_validate_trace_desc(ha) == DDI_SUCCESS)) {
 159      -                tracing = 1;
      161 +        if (ha == NULL && (ha = ql_hba.first->base_address) == NULL) {
      162 +                return;
      163 +        }
 160  164  
 161      -                TRACE_BUFFER_LOCK(ha);
      165 +        desc = ha->ql_trace_desc;
 162  166  
      167 +        (void) bzero((void *)&buf[0], EL_BUFFER_RESERVE + 3);
      168 +        fmt1 = &buf[0];
      169 +
      170 +        TRACE_BUFFER_LOCK(ha);
      171 +
      172 +        /* locate the entry to be filled out */
      173 +        cindex = desc->nindex;
      174 +        entry = &desc->trace_buffer[cindex];
      175 +
      176 +        count = desc->count;
      177 +
      178 +        desc->end = desc->nindex;
      179 +        desc->nindex++;
      180 +
      181 +        if (desc->nindex == desc->nentries) {
      182 +                desc->nindex = 0;
      183 +        }
      184 +
      185 +        if (desc->csize < desc->nentries) {
      186 +                desc->csize++;
      187 +        } else {
 163  188                  /*
 164      -                 * Ensure enough space for the string. Wrap to
 165      -                 * start when default message allocation size
 166      -                 * would overrun the end.
      189 +                 * once wrapped, csize is fixed.
      190 +                 * so we have to adjust start point
 167  191                   */
 168      -                if ((ha->el_trace_desc->next + EL_BUFFER_RESERVE) >=
 169      -                    ha->el_trace_desc->trace_buffer_size) {
 170      -                        fmt = ha->el_trace_desc->trace_buffer;
 171      -                        ha->el_trace_desc->next = 0;
 172      -                } else {
 173      -                        fmt = ha->el_trace_desc->trace_buffer +
 174      -                            ha->el_trace_desc->next;
 175      -                }
      192 +                desc->start = desc->nindex;
 176  193          }
 177      -        /* if no buffer use the stack */
 178      -        if (fmt == NULL) {
 179      -                fmt = fmt2;
 180      -        }
 181  194  
 182      -        va_start(vl, ce);
      195 +        gethrestime(&time);
 183  196  
      197 +        rval = snprintf(fmt1, (size_t)EL_BUFFER_RESERVE,
      198 +            QL_BANG "%d=>QEL %s(%d,%d,%d):: %s, ", count, QL_NAME,
      199 +            ha->instance, ha->vp_index, ha->pci_function_number, fn);
      200 +
      201 +        rval1 = rval;
      202 +
      203 +        va_start(vl, ce);
 184  204          s = va_arg(vl, char *);
 185  205  
 186      -        if (ql_enable_ellock) {
      206 +        fmt = fmt1 + rval;
      207 +
      208 +        tmp = vsnprintf(fmt,
      209 +            (size_t)(uint32_t)((int)EL_BUFFER_RESERVE - rval), s, vl);
      210 +
      211 +        va_end(vl);
      212 +
      213 +        rval += tmp;
      214 +
      215 +        if (rval > QL_LOG_LENGTH - 1) {
      216 +                left = rval - (QL_LOG_LENGTH - 1);
      217 +
      218 +                /* store the remaining string */
      219 +                (void) strncpy(buf1, fmt1 + (QL_LOG_LENGTH - 1), left);
      220 +
      221 +                (void) strncpy(entry->buf, fmt1, (QL_LOG_LENGTH - 1));
      222 +                entry->buf[QL_LOG_LENGTH - 1] = '\n';
      223 +
      224 +                bcopy((void *)&time, (void *)&entry->hs_time,
      225 +                    sizeof (timespec_t));
      226 +
 187  227                  /*
 188      -                 * Used when messages are *maybe* being lost.  Adds
 189      -                 * a unique number to the message so one can see if
 190      -                 * any messages have been dropped. NB: This slows
 191      -                 * down the driver, which may make the issue disappear.
      228 +                 * remaining msg will be stored in the nex entry
      229 +                 * with same timestamp and same sequence number
 192  230                   */
 193      -                GLOBAL_EL_LOCK();
 194      -                el_msg_num = ++el_message_number;
 195      -                GLOBAL_EL_UNLOCK();
      231 +                cindex = desc->nindex;
      232 +                entry = &desc->trace_buffer[cindex];
 196  233  
 197      -                rval = (int)snprintf(fmt, (size_t)EL_BUFFER_RESERVE,
 198      -                    QL_BANG "QEL%d %s(%d,%d): %s, ", el_msg_num, QL_NAME,
 199      -                    ha->instance, ha->vp_index, fn);
 200      -                fmt1 = fmt + rval;
 201      -                tmp = (int)vsnprintf(fmt1,
 202      -                    (size_t)(uint32_t)((int)EL_BUFFER_RESERVE - rval), s, vl);
 203      -                rval += tmp;
 204      -        } else {
 205      -                rval = (int)snprintf(fmt, (size_t)EL_BUFFER_RESERVE,
 206      -                    QL_BANG "QEL %s(%d,%d): %s, ", QL_NAME, ha->instance,
 207      -                    ha->vp_index, fn);
 208      -                fmt1 = fmt + rval;
 209      -                tmp = (int)vsnprintf(fmt1,
 210      -                    (size_t)(uint32_t)((int)EL_BUFFER_RESERVE - rval), s, vl);
 211      -                rval += tmp;
 212      -        }
      234 +                desc->end = desc->nindex;
      235 +                desc->nindex++;
 213  236  
 214      -        /*
 215      -         * Calculate the offset where the next message will go,
 216      -         * skipping the NULL.
 217      -         */
 218      -        if (tracing) {
 219      -                uint16_t next = (uint16_t)(rval += 1);
 220      -                ha->el_trace_desc->next += next;
      237 +                if (desc->nindex == desc->nentries) {
      238 +                        desc->nindex = 0;
      239 +                }
      240 +
      241 +                if (desc->csize < desc->nentries) {
      242 +                        desc->csize++;
      243 +                } else {
      244 +                        desc->start = desc->nindex;
      245 +                }
      246 +
      247 +                (void) strncpy(&entry->buf[0], fmt1, rval1);
      248 +                (void) strncpy(&entry->buf[rval1], &buf1[0], left);
      249 +                entry->buf[rval1 + left] = 0;
      250 +
      251 +                bcopy((void *)&time, (void *)&entry->hs_time,
      252 +                    sizeof (timespec_t));
      253 +
      254 +                if (CFG_IST(ha, CFG_ENABLE_EXTENDED_LOGGING)) {
      255 +                        cmn_err(ce, fmt1);
      256 +                }
      257 +
      258 +                desc->count++;
      259 +
 221  260                  TRACE_BUFFER_UNLOCK(ha);
      261 +                return;
 222  262          }
 223  263  
      264 +        desc->count++;
      265 +        bcopy((void *)&time, (void *)&entry->hs_time,
      266 +            sizeof (timespec_t));
      267 +
      268 +        (void) strncpy(entry->buf, fmt1, sizeof (entry->buf));
      269 +        entry->buf[rval] = 0;
      270 +
      271 +        TRACE_BUFFER_UNLOCK(ha);
      272 +
 224  273          if (CFG_IST(ha, CFG_ENABLE_EXTENDED_LOGGING)) {
 225      -                cmn_err(ce, fmt);
      274 +                cmn_err(ce, fmt1);
 226  275          }
 227      -
 228      -        va_end(vl);
 229  276  }
 230  277  
 231  278  /*
 232      - * ql_el_msg
      279 + * ql_dbg_msg
 233  280   *      Extended logging message
 234  281   *
 235  282   * Input:
 236  283   *      ha:     adapter state pointer.
 237  284   *      fn:     function name.
 238  285   *      ce:     level
 239  286   *      ...:    Variable argument list.
 240  287   *
 241  288   * Context:
 242  289   *      Kernel/Interrupt context.
 243  290   */
 244  291  void
 245      -ql_dbg_msg(const char *fn, int ce, ...)
      292 +ql_dbg_msg(ql_adapter_state_t *ha, const char *fn, int ce, ...)
 246  293  {
 247  294          uint32_t        el_msg_num;
 248  295          char            *s;
 249      -        char            fmt[256];
      296 +        char            fmt[EL_BUFFER_RESERVE];
 250  297          va_list         vl;
 251  298  
 252  299          va_start(vl, ce);
 253  300  
 254  301          s = va_arg(vl, char *);
 255  302  
 256  303          if (ql_enable_ellock) {
 257  304                  /*
 258  305                   * Used when messages are *maybe* being lost.  Adds
 259  306                   * a unique number to the message to one can see if
 260  307                   * any messages have been dropped. NB: This slows
 261  308                   * down the driver, which may make the issue disappear.
 262  309                   */
 263  310                  GLOBAL_EL_LOCK();
 264  311                  el_msg_num = ++el_message_number;
 265  312                  GLOBAL_EL_UNLOCK();
 266      -                (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP%d: %s %s, %s",
 267      -                    el_msg_num, QL_NAME, fn, s);
      313 +                if (ha == NULL) {
      314 +                        (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP%d: %s, "
      315 +                            "%s", el_msg_num, fn, s);
      316 +                } else {
      317 +                        (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP%d: %s"
      318 +                            "(%d,%d,%d): %s", el_msg_num, fn, ha->instance,
      319 +                            ha->vp_index, ha->pci_function_number, s);
      320 +                }
 268  321          } else {
 269      -                (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP: %s %s, %s",
 270      -                    QL_NAME, fn, s);
      322 +                if (ha == NULL) {
      323 +                        (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP: %s, "
      324 +                            "%s", fn, s);
      325 +                } else {
      326 +                        (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP: %s"
      327 +                            "(%d,%d,%d): %s", fn, ha->instance, ha->vp_index,
      328 +                            ha->pci_function_number, s);
      329 +                }
 271  330          }
 272  331  
 273  332          vcmn_err(ce, fmt, vl);
 274  333  
 275  334          va_end(vl);
 276  335  }
 277  336  
 278  337  /*
 279  338   * ql_stacktrace
 280  339   *      Prints out current stack
↓ open down ↓ 50 lines elided ↑ open up ↑
 331  390   *      Kernel/Interrupt context.
 332  391   */
 333  392  int
 334  393  ql_flash_errlog(ql_adapter_state_t *ha, uint16_t code, uint16_t d1,
 335  394      uint16_t d2, uint16_t d3)
 336  395  {
 337  396          char            *s;
 338  397          uint32_t        marker[2], fdata[2], faddr;
 339  398          int             rval;
 340  399  
 341      -        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
      400 +        QL_PRINT_3(ha, "started\n");
 342  401  
 343  402          if (ha->flash_errlog_start == 0) {
 344  403                  return (QL_NOT_SUPPORTED);
 345  404          }
 346  405  
 347  406          EL(ha, "code=%xh, d1=%xh, d2=%xh, d3=%xh\n", code, d1, d2, d3);
 348  407  
 349  408          /*
 350  409           * If marker not already found, locate or write marker.
 351  410           */
↓ open down ↓ 58 lines elided ↑ open up ↑
 410  469          /*
 411  470           * Store error.
 412  471           */
 413  472          fdata[0] = SHORT_TO_LONG(d1, code);
 414  473          fdata[1] = SHORT_TO_LONG(d3, d2);
 415  474          rval = ql_flash_errlog_store(ha, fdata);
 416  475          if (rval != QL_SUCCESS) {
 417  476                  EL(ha, "failed error write=%xh\n", rval);
 418  477          } else {
 419  478                  /*EMPTY*/
 420      -                QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
      479 +                QL_PRINT_3(ha, "done\n");
 421  480          }
 422  481  
 423  482          return (rval);
 424  483  }
 425  484  
 426  485  /*
 427  486   * ql_flash_errlog_store
 428  487   *      Stores error to flash.
 429  488   *      Entry Layout:
 430  489   *              uint32_t TimeStamp;
↓ open down ↓ 13 lines elided ↑ open up ↑
 444  503   * Context:
 445  504   *      Kernel/Interrupt context.
 446  505   */
 447  506  static int
 448  507  ql_flash_errlog_store(ql_adapter_state_t *ha, uint32_t *fdata)
 449  508  {
 450  509          int             rval;
 451  510          uint64_t        time;
 452  511          uint32_t        d1, d2, faddr;
 453  512  
 454      -        QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
      513 +        QL_PRINT_3(ha, "started\n");
 455  514  
 456  515          /* Locate first empty entry */
 457  516          for (;;) {
 458  517                  if (ha->flash_errlog_ptr >=
 459  518                      ha->flash_errlog_start + FLASH_ERRLOG_SIZE) {
 460  519                          EL(ha, "log full\n");
 461  520                          return (QL_MEMORY_FULL);
 462  521                  }
 463  522  
 464  523                  faddr = ha->flash_data_addr | ha->flash_errlog_ptr;
↓ open down ↓ 15 lines elided ↑ open up ↑
 480  539                          (void) ql_24xx_write_flash(ha, faddr++, MSD(time));
 481  540                          (void) ql_24xx_write_flash(ha, faddr++, *fdata++);
 482  541                          (void) ql_24xx_write_flash(ha, faddr++, *fdata);
 483  542  
 484  543                          /* Enable flash write-protection. */
 485  544                          ql_24xx_protect_flash(ha);
 486  545                          break;
 487  546                  }
 488  547          }
 489  548  
 490      -        QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
      549 +        QL_PRINT_3(ha, "done\n");
 491  550  
 492  551          return (QL_SUCCESS);
 493      -}
 494      -
 495      -/*
 496      - * ql_dump_el_trace_buffer
 497      - *       Outputs extended logging trace buffer.
 498      - *
 499      - * Input:
 500      - *      ha:     adapter state pointer.
 501      - */
 502      -void
 503      -ql_dump_el_trace_buffer(ql_adapter_state_t *ha)
 504      -{
 505      -        char            *dump_start = NULL;
 506      -        char            *dump_current = NULL;
 507      -        char            *trace_start;
 508      -        char            *trace_end;
 509      -        int             wrapped = 0;
 510      -        int             rval;
 511      -
 512      -        TRACE_BUFFER_LOCK(ha);
 513      -
 514      -        rval = ql_validate_trace_desc(ha);
 515      -        if (rval != NULL) {
 516      -                cmn_err(CE_CONT, "%s(%d) Dump EL trace - invalid desc\n",
 517      -                    QL_NAME, ha->instance);
 518      -        } else if ((dump_start = ql_find_trace_start(ha)) != NULL) {
 519      -                dump_current = dump_start;
 520      -                trace_start = ha->el_trace_desc->trace_buffer;
 521      -                trace_end = trace_start +
 522      -                    ha->el_trace_desc->trace_buffer_size;
 523      -
 524      -                cmn_err(CE_CONT, "%s(%d) Dump EL trace - start %p %p\n",
 525      -                    QL_NAME, ha->instance,
 526      -                    (void *)dump_start, (void *)trace_start);
 527      -
 528      -                while (((uintptr_t)dump_current - (uintptr_t)trace_start) <=
 529      -                    (uintptr_t)ha->el_trace_desc->trace_buffer_size) {
 530      -                        /* Show it... */
 531      -                        cmn_err(CE_CONT, "%p - %s", (void *)dump_current,
 532      -                            dump_current);
 533      -                        /* Make the next the current */
 534      -                        dump_current += (strlen(dump_current) + 1);
 535      -                        /* check for wrap */
 536      -                        if ((dump_current + EL_BUFFER_RESERVE) >= trace_end) {
 537      -                                dump_current = trace_start;
 538      -                                wrapped = 1;
 539      -                        } else if (wrapped) {
 540      -                                /* Don't go past next. */
 541      -                                if ((trace_start + ha->el_trace_desc->next) <=
 542      -                                    dump_current) {
 543      -                                        break;
 544      -                                }
 545      -                        } else if (*dump_current == NULL) {
 546      -                                break;
 547      -                        }
 548      -                }
 549      -        }
 550      -        TRACE_BUFFER_UNLOCK(ha);
 551      -}
 552      -
 553      -/*
 554      - * ql_validate_trace_desc
 555      - *       Ensures the extended logging trace descriptor is good
 556      - *
 557      - * Input:
 558      - *      ha:     adapter state pointer.
 559      - *
 560      - * Returns:
 561      - *      ql local function return status code.
 562      - */
 563      -int
 564      -ql_validate_trace_desc(ql_adapter_state_t *ha)
 565      -{
 566      -        int     rval = DDI_SUCCESS;
 567      -
 568      -        if (ha->el_trace_desc == NULL) {
 569      -                rval = DDI_FAILURE;
 570      -        } else if (ha->el_trace_desc->trace_buffer == NULL) {
 571      -                rval = DDI_FAILURE;
 572      -        }
 573      -        return (rval);
 574      -}
 575      -
 576      -/*
 577      - * ql_find_trace_start
 578      - *       Locate the oldest extended logging trace entry.
 579      - *
 580      - * Input:
 581      - *      ha:     adapter state pointer.
 582      - *
 583      - * Returns:
 584      - *      Pointer to a string.
 585      - *
 586      - * Context:
 587      - *      Kernel/Interrupt context.
 588      - */
 589      -char *
 590      -ql_find_trace_start(ql_adapter_state_t *ha)
 591      -{
 592      -        char    *trace_start = 0;
 593      -        char    *trace_next  = 0;
 594      -
 595      -        trace_next = ha->el_trace_desc->trace_buffer + ha->el_trace_desc->next;
 596      -
 597      -        /*
 598      -         * if the buffer has not wrapped next will point at a null so
 599      -         * start is the beginning of the buffer.  if next points at a char
 600      -         * then we must traverse the buffer until a null is detected and
 601      -         * that will be the beginning of the oldest whole object in the buffer
 602      -         * which is the start.
 603      -         */
 604      -
 605      -        if ((trace_next + EL_BUFFER_RESERVE) >=
 606      -            (ha->el_trace_desc->trace_buffer +
 607      -            ha->el_trace_desc->trace_buffer_size)) {
 608      -                trace_start = ha->el_trace_desc->trace_buffer;
 609      -        } else if (*trace_next != NULL) {
 610      -                trace_start = trace_next + (strlen(trace_next) + 1);
 611      -        } else {
 612      -                trace_start = ha->el_trace_desc->trace_buffer;
 613      -        }
 614      -        return (trace_start);
 615  552  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX