fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard/* Copyright 2009 QLogic Corporation */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard#pragma ident "Copyright 2009 QLogic Corporation; ql_debug.c"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Qlogic ISP22xx/ISP23xx/ISP24xx FCA driver source
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ***********************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * NOTICE **
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * ALL RIGHTS RESERVED **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ***********************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_apps.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_api.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_flash_errlog_store(ql_adapter_state_t *, uint32_t *);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardint ql_validate_trace_desc(ql_adapter_state_t *ha);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardchar *ql_find_trace_start(ql_adapter_state_t *ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Global Data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint32_t el_message_number = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteuint32_t ql_enable_ellock = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern int getpcstack(pc_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern char *kobj_getsymname(uintptr_t, ulong_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_dump_buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Outputs buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * string: Null terminated string (no newline at end).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buffer: buffer address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wd_size: word size 8 bits
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * count: number of words.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_dump_buffer(uint8_t *b8, uint8_t wd_size, uint32_t count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char str[256], *sp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *b32 = (uint32_t *)b8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t *b16 = (uint16_t *)b8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp = &str[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (wd_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 32:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, " 0 4 8 C\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "----------------------------------------\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt <= count; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(sp, "%10x", *b32++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp += 10;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt % 4 == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s\n", str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp = &str[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 16:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, " 0 2 4 6 8 A C"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " E\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "------------------------------------------"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "------\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt <= count; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(sp, "%6x", *b16++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp += 6;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt % 8 == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s\n", str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp = &str[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 8:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, " 0 1 2 3 4 5 6 7 8 9 "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "A B C D E F\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "---------------------------------"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "-------------------------------\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1; cnt <= count; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(sp, "%4x", *b8++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp += 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt % 16 == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s\n", str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sp = &str[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sp != &str[0]) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s\n", str);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_el_msg
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Extended logging message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fn: function name.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ce: level
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ...: Variable argument list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel/Interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_el_msg(ql_adapter_state_t *ha, const char *fn, int ce, ...)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t el_msg_num;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *s, *fmt = 0, *fmt1 = 0;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char fmt2[256];
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard int rval, tmp;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard int tracing = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_list vl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /* Tracing is the default but it can be disabled. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((CFG_IST(ha, CFG_DISABLE_EXTENDED_LOGGING_TRACE) == 0) &&
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (rval = ql_validate_trace_desc(ha) == DDI_SUCCESS)) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard tracing = 1;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard TRACE_BUFFER_LOCK(ha);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Ensure enough space for the string. Wrap to
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * start when default message allocation size
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * would overrun the end.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if ((ha->el_trace_desc->next + EL_BUFFER_RESERVE) >=
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->el_trace_desc->trace_buffer_size) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard fmt = ha->el_trace_desc->trace_buffer;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->el_trace_desc->next = 0;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard fmt = ha->el_trace_desc->trace_buffer +
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->el_trace_desc->next;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /* if no buffer use the stack */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if (fmt == NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard fmt = fmt2;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_start(vl, ce);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s = va_arg(vl, char *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_enable_ellock) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Used when messages are *maybe* being lost. Adds
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * a unique number to the message so one can see if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * any messages have been dropped. NB: This slows
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * down the driver, which may make the issue disappear.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GLOBAL_EL_LOCK();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte el_msg_num = ++el_message_number;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GLOBAL_EL_UNLOCK();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval = (int)snprintf(fmt, (size_t)EL_BUFFER_RESERVE,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_BANG "QEL%d %s(%d,%d): %s, ", el_msg_num, QL_NAME,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard ha->instance, ha->vp_index, fn);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard fmt1 = fmt + rval;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard tmp = (int)vsnprintf(fmt1,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (size_t)(uint32_t)((int)EL_BUFFER_RESERVE - rval), s, vl);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval += tmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval = (int)snprintf(fmt, (size_t)EL_BUFFER_RESERVE,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard QL_BANG "QEL %s(%d,%d): %s, ", QL_NAME, ha->instance,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->vp_index, fn);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard fmt1 = fmt + rval;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard tmp = (int)vsnprintf(fmt1,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (size_t)(uint32_t)((int)EL_BUFFER_RESERVE - rval), s, vl);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval += tmp;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Calculate the offset where the next message will go,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * skipping the NULL.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if (tracing) {
7a2b99c0f2ca8f0910b76c47c895d7c6a23674deDaniel Beauregard uint16_t next = (uint16_t)(rval += 1);
7a2b99c0f2ca8f0910b76c47c895d7c6a23674deDaniel Beauregard ha->el_trace_desc->next += next;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard TRACE_BUFFER_UNLOCK(ha);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if (CFG_IST(ha, CFG_ENABLE_EXTENDED_LOGGING)) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard cmn_err(ce, fmt);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard va_end(vl);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard}
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard/*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ql_el_msg
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Extended logging message
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Input:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ha: adapter state pointer.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * fn: function name.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ce: level
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ...: Variable argument list.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Context:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Kernel/Interrupt context.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardvoid
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardql_dbg_msg(const char *fn, int ce, ...)
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard{
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard uint32_t el_msg_num;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *s;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char fmt[256];
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard va_list vl;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard va_start(vl, ce);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard s = va_arg(vl, char *);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if (ql_enable_ellock) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Used when messages are *maybe* being lost. Adds
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * a unique number to the message to one can see if
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * any messages have been dropped. NB: This slows
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * down the driver, which may make the issue disappear.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard GLOBAL_EL_LOCK();
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard el_msg_num = ++el_message_number;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard GLOBAL_EL_UNLOCK();
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP%d: %s %s, %s",
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard el_msg_num, QL_NAME, fn, s);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (void) snprintf(fmt, EL_BUFFER_RESERVE, "QLP: %s %s, %s",
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard QL_NAME, fn, s);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vcmn_err(ce, fmt, vl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte va_end(vl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_stacktrace
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prints out current stack
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel/Interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_stacktrace(ql_adapter_state_t *ha)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int depth, i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pc_t pcstack[DEBUG_STK_DEPTH];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *sym = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ulong_t off;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte depth = getpcstack(&pcstack[0], DEBUG_STK_DEPTH);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s(%d,%d): ---------- \n", QL_NAME, ha->instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->vp_index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < MIN(depth, DEBUG_STK_DEPTH); i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sym = kobj_getsymname((uintptr_t)pcstack[i], &off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sym == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s(%d,%d): sym is NULL\n", QL_NAME,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->instance, ha->vp_index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s(%d,%d): %s+%lx\n", QL_NAME,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->instance, ha->vp_index, sym ? sym : "?", off);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_CONT, "%s(%d,%d): ---------- \n", QL_NAME, ha->instance,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->vp_index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_flash_errlog
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Adds error to flash error log.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Entry Layout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * uint32_t TimeStamp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * uint16_t CodeData[4];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code: Error code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * d1-d3: Error code data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql local function return status code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel/Interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_flash_errlog(ql_adapter_state_t *ha, uint16_t code, uint16_t d1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t d2, uint16_t d3)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *s;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t marker[2], fdata[2], faddr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->flash_errlog_start == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (QL_NOT_SUPPORTED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "code=%xh, d1=%xh, d2=%xh, d3=%xh\n", code, d1, d2, d3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If marker not already found, locate or write marker.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ha->flags & FLASH_ERRLOG_MARKER)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Create marker. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte marker[0] = CHAR_TO_LONG(ha->fw_subminor_version,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->fw_minor_version, ha->fw_major_version, 'S');
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Version should be of the format: YYYYMMDD-v.vv
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((strlen(QL_VERSION) > 9) && (QL_VERSION[8] == '-')) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s = &QL_VERSION[9];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s = QL_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (marker[1] = 0; *s != '\0'; s++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*s >= '0' && *s <= '9') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte marker[1] <<= 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte marker[1] |= *s - '0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (*s != '.') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Locate marker. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flash_errlog_ptr = ha->flash_errlog_start;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (;;) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard faddr = ha->flash_data_addr | ha->flash_errlog_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_read_flash(ha, faddr++, &fdata[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_read_flash(ha, faddr++, &fdata[1]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdata[0] == 0xffffffff && fdata[1] == 0xffffffff) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_read_flash(ha, faddr++, &fdata[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_read_flash(ha, faddr++, &fdata[1]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flash_errlog_ptr += FLASH_ERRLOG_ENTRY_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->flash_errlog_ptr >=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flash_errlog_start + FLASH_ERRLOG_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "log full\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (QL_MEMORY_FULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fdata[0] == marker[0] && fdata[1] == marker[1]) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flags |= FLASH_ERRLOG_MARKER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No marker, write it. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ha->flags & FLASH_ERRLOG_MARKER)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flags |= FLASH_ERRLOG_MARKER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_flash_errlog_store(ha, marker);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed marker write=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Store error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdata[0] = SHORT_TO_LONG(d1, code);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fdata[1] = SHORT_TO_LONG(d3, d2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_flash_errlog_store(ha, fdata);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed error write=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_flash_errlog_store
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Stores error to flash.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Entry Layout:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * uint32_t TimeStamp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * uint16_t CodeData[4];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fdata: Error code plus data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha->flash_errlog_ptr: Current Flash error pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Output:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha->flash_errlog_ptr: updated pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql local function return status code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel/Interrupt context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_flash_errlog_store(ql_adapter_state_t *ha, uint32_t *fdata)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint64_t time;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t d1, d2, faddr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Locate first empty entry */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (;;) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->flash_errlog_ptr >=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flash_errlog_start + FLASH_ERRLOG_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "log full\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (QL_MEMORY_FULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard faddr = ha->flash_data_addr | ha->flash_errlog_ptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flash_errlog_ptr += FLASH_ERRLOG_ENTRY_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_read_flash(ha, faddr, &d1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_read_flash(ha, faddr + 1, &d2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (d1 == 0xffffffff && d2 == 0xffffffff) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) drv_getparm(TIME, &time);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Enable flash write. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ql_24xx_unprotect_flash(ha)) !=
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_SUCCESS) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard EL(ha, "unprotect_flash failed, rval=%xh\n",
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard rval);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard return (rval);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_write_flash(ha, faddr++, LSD(time));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_write_flash(ha, faddr++, MSD(time));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_write_flash(ha, faddr++, *fdata++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_write_flash(ha, faddr++, *fdata);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Enable flash write-protection. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_24xx_protect_flash(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (QL_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard/*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ql_dump_el_trace_buffer
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Outputs extended logging trace buffer.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Input:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ha: adapter state pointer.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardvoid
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardql_dump_el_trace_buffer(ql_adapter_state_t *ha)
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard{
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *dump_start = NULL;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *dump_current = NULL;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *trace_start;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *trace_end;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard int wrapped = 0;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard int rval;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard TRACE_BUFFER_LOCK(ha);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval = ql_validate_trace_desc(ha);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if (rval != NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard cmn_err(CE_CONT, "%s(%d) Dump EL trace - invalid desc\n",
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard QL_NAME, ha->instance);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else if ((dump_start = ql_find_trace_start(ha)) != NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dump_current = dump_start;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard trace_start = ha->el_trace_desc->trace_buffer;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard trace_end = trace_start +
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->el_trace_desc->trace_buffer_size;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard cmn_err(CE_CONT, "%s(%d) Dump EL trace - start %p %p\n",
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard QL_NAME, ha->instance,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (void *)dump_start, (void *)trace_start);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard while (((uintptr_t)dump_current - (uintptr_t)trace_start) <=
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard (uintptr_t)ha->el_trace_desc->trace_buffer_size) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /* Show it... */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard cmn_err(CE_CONT, "%p - %s", (void *)dump_current,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dump_current);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /* Make the next the current */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dump_current += (strlen(dump_current) + 1);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /* check for wrap */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if ((dump_current + EL_BUFFER_RESERVE) >= trace_end) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dump_current = trace_start;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard wrapped = 1;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else if (wrapped) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /* Don't go past next. */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if ((trace_start + ha->el_trace_desc->next) <=
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dump_current) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard break;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else if (*dump_current == NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard break;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard TRACE_BUFFER_UNLOCK(ha);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard}
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard/*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ql_validate_trace_desc
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Ensures the extended logging trace descriptor is good
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Input:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ha: adapter state pointer.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Returns:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ql local function return status code.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardint
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardql_validate_trace_desc(ql_adapter_state_t *ha)
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard{
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard int rval = DDI_SUCCESS;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if (ha->el_trace_desc == NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval = DDI_FAILURE;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else if (ha->el_trace_desc->trace_buffer == NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard rval = DDI_FAILURE;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard return (rval);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard}
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard/*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ql_find_trace_start
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Locate the oldest extended logging trace entry.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Input:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * ha: adapter state pointer.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Returns:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Pointer to a string.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Context:
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * Kernel/Interrupt context.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardchar *
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregardql_find_trace_start(ql_adapter_state_t *ha)
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard{
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *trace_start = 0;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard char *trace_next = 0;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard trace_next = ha->el_trace_desc->trace_buffer + ha->el_trace_desc->next;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard /*
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * if the buffer has not wrapped next will point at a null so
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * start is the beginning of the buffer. if next points at a char
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * then we must traverse the buffer until a null is detected and
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * that will be the beginning of the oldest whole object in the buffer
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard * which is the start.
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard */
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if ((trace_next + EL_BUFFER_RESERVE) >=
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard (ha->el_trace_desc->trace_buffer +
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->el_trace_desc->trace_buffer_size)) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard trace_start = ha->el_trace_desc->trace_buffer;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else if (*trace_next != NULL) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard trace_start = trace_next + (strlen(trace_next) + 1);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard } else {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard trace_start = ha->el_trace_desc->trace_buffer;
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard }
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard return (trace_start);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard}