/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright 2009 QLogic Corporation */
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "Copyright 2009 QLogic Corporation; ql_debug.c"
/*
*
* ***********************************************************************
* * **
* * NOTICE **
* * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION **
* * ALL RIGHTS RESERVED **
* * **
* ***********************************************************************
*
*/
#include <ql_apps.h>
#include <ql_api.h>
#include <ql_debug.h>
/*
* Global Data.
*/
extern int getpcstack(pc_t *, int);
/*
* ql_dump_buffer
* Outputs buffer.
*
* Input:
* string: Null terminated string (no newline at end).
* buffer: buffer address.
* wd_size: word size 8 bits
* count: number of words.
*/
void
{
switch (wd_size) {
case 32:
sp += 10;
if (cnt % 4 == 0) {
}
}
break;
case 16:
" E\n");
"------\n");
sp += 6;
if (cnt % 8 == 0) {
}
}
break;
case 8:
"A B C D E F\n");
"-------------------------------\n");
sp += 4;
if (cnt % 16 == 0) {
}
}
break;
default:
break;
}
}
}
/*
* ql_el_msg
* Extended logging message
*
* Input:
* ha: adapter state pointer.
* fn: function name.
* ce: level
* ...: Variable argument list.
*
* Context:
*/
void
{
int tracing = 0;
/* Tracing is the default but it can be disabled. */
tracing = 1;
/*
* Ensure enough space for the string. Wrap to
* start when default message allocation size
* would overrun the end.
*/
} else {
}
}
/* if no buffer use the stack */
}
if (ql_enable_ellock) {
/*
* Used when messages are *maybe* being lost. Adds
* a unique number to the message so one can see if
* any messages have been dropped. NB: This slows
* down the driver, which may make the issue disappear.
*/
} else {
}
/*
* Calculate the offset where the next message will go,
* skipping the NULL.
*/
if (tracing) {
}
}
}
/*
* ql_el_msg
* Extended logging message
*
* Input:
* ha: adapter state pointer.
* fn: function name.
* ce: level
* ...: Variable argument list.
*
* Context:
*/
void
{
char *s;
if (ql_enable_ellock) {
/*
* Used when messages are *maybe* being lost. Adds
* a unique number to the message to one can see if
* any messages have been dropped. NB: This slows
* down the driver, which may make the issue disappear.
*/
} else {
}
}
/*
* ql_stacktrace
* Prints out current stack
*
* Input:
* ha: adapter state pointer.
*
* Context:
*/
void
{
int depth, i;
} else {
}
}
}
/*
* ql_flash_errlog
* Adds error to flash error log.
* Entry Layout:
* uint32_t TimeStamp;
* uint16_t CodeData[4];
*
* Input:
* ha: adapter state pointer.
* code: Error code
* d1-d3: Error code data
*
* Returns:
* ql local function return status code.
*
* Context:
*/
int
{
char *s;
int rval;
if (ha->flash_errlog_start == 0) {
return (QL_NOT_SUPPORTED);
}
/*
* If marker not already found, locate or write marker.
*/
/* Create marker. */
/*
* Version should be of the format: YYYYMMDD-v.vv
*/
s = &QL_VERSION[9];
} else {
s = QL_VERSION;
}
if (*s >= '0' && *s <= '9') {
} else if (*s != '.') {
break;
}
}
/* Locate marker. */
for (;;) {
break;
}
if (ha->flash_errlog_ptr >=
return (QL_MEMORY_FULL);
}
break;
}
}
/* No marker, write it. */
if (rval != QL_SUCCESS) {
return (rval);
}
}
}
/*
* Store error.
*/
if (rval != QL_SUCCESS) {
} else {
/*EMPTY*/
}
return (rval);
}
/*
* ql_flash_errlog_store
* Stores error to flash.
* Entry Layout:
* uint32_t TimeStamp;
* uint16_t CodeData[4];
*
* Input:
* ha: adapter state pointer.
* fdata: Error code plus data.
* ha->flash_errlog_ptr: Current Flash error pointer.
*
* Output:
* ha->flash_errlog_ptr: updated pointer.
*
* Returns:
* ql local function return status code.
*
* Context:
*/
static int
{
int rval;
/* Locate first empty entry */
for (;;) {
if (ha->flash_errlog_ptr >=
return (QL_MEMORY_FULL);
}
/* Enable flash write. */
QL_SUCCESS) {
rval);
return (rval);
}
/* Enable flash write-protection. */
break;
}
}
return (QL_SUCCESS);
}
/*
* ql_dump_el_trace_buffer
* Outputs extended logging trace buffer.
*
* Input:
* ha: adapter state pointer.
*/
void
{
char *trace_start;
char *trace_end;
int wrapped = 0;
int rval;
trace_end = trace_start +
(void *)dump_start, (void *)trace_start);
/* Show it... */
/* Make the next the current */
/* check for wrap */
wrapped = 1;
} else if (wrapped) {
/* Don't go past next. */
dump_current) {
break;
}
} else if (*dump_current == NULL) {
break;
}
}
}
}
/*
* ql_validate_trace_desc
* Ensures the extended logging trace descriptor is good
*
* Input:
* ha: adapter state pointer.
*
* Returns:
* ql local function return status code.
*/
int
{
rval = DDI_FAILURE;
rval = DDI_FAILURE;
}
return (rval);
}
/*
* ql_find_trace_start
* Locate the oldest extended logging trace entry.
*
* Input:
* ha: adapter state pointer.
*
* Returns:
* Pointer to a string.
*
* Context:
*/
char *
{
char *trace_start = 0;
char *trace_next = 0;
/*
* if the buffer has not wrapped next will point at a null so
* start is the beginning of the buffer. if next points at a char
* then we must traverse the buffer until a null is detected and
* that will be the beginning of the oldest whole object in the buffer
* which is the start.
*/
if ((trace_next + EL_BUFFER_RESERVE) >=
} else if (*trace_next != NULL) {
} else {
}
return (trace_start);
}