emlxs_msg.c revision 291a2b48b9adcd7b3666c34e80ba6411929afe7f
/*
* 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 Emulex. All rights reserved.
* Use is subject to License terms.
*/
#define DEF_MSG_STRUCT /* Needed for emlxs_messages.h in emlxs_msg.h */
#include <emlxs.h>
/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
{
char buf[40];
#ifdef MSI_SUPPORT
#endif /* MSI_SUPPORT */
/* Check if log is already created */
return (0);
}
/* Clear the log */
/* Allocate the memory needed for the log file */
"?%s%d: Unable to allocate log memory. log=%p",
return (0);
}
/* Initialize */
/* Get the current interrupt block cookie */
&iblock);
/* Create the log mutex lock */
}
#ifdef MSI_SUPPORT
else {
/* Allocate a temporary interrupt handle */
actual = 0;
ret =
"?%s%d: Unable to allocate temporary interrupt "
"handle. ret=%d actual=%d", DRIVER_NAME,
/* Free the log buffer */
return (0);
}
/* Get the current interrupt priority */
if (ret != DDI_SUCCESS) {
"?%s%d: Unable to get interrupt priority. ret=%d",
/* Free the log buffer */
return (0);
}
/* Create the log mutex lock */
(void *)((unsigned long)intr_pri));
/* Free the temporary handle */
(void) ddi_intr_free(handle);
}
#endif
return (1);
} /* emlxs_msg_log_create() */
{
uint32_t i;
/* Check if log is already destroyed */
"?%s%d: message log already destroyed. log=%p",
return (1);
}
/* If events are being logged there might be */
/* threads waiting so release them */
if (hba->log_events) {
hba->log_events = 0;
DELAYMS(1);
}
/* Destroy the lock */
/* Free the context buffers */
}
}
/* Free the log buffer */
/* Clear the log */
return (1);
} /* emlxs_msg_log_destroy() */
void
{
} /* emlxs_setup_abts_ct */
void
emlxs_abts_ct_thread(void *arg)
{
void (*func) ();
/*
* Allocated by the emlxs_msg_log()
*/
thread_exit();
} /* emlxs_abts_ct_thread */
{
uint32_t i;
/* Get the log file for this instance */
/* Check if log is initialized */
"?%s%d: message log not created. log=%p",
} else {
"?%s%d.%d: message log not created. log=%p",
(void *)log);
}
}
return (1);
}
/* Get the pointer to the last log entry */
} else {
}
/* Check if this matches the last message */
/* If the same message is being logged then increment */
return (0);
/* Get the pointer to the next log entry */
/* Increment and check the next entry index */
}
case EMLXS_DEBUG:
msg2 = &emlxs_debug_msg;
break;
case EMLXS_NOTICE:
msg2 = &emlxs_notice_msg;
break;
case EMLXS_WARNING:
break;
case EMLXS_ERROR:
msg2 = &emlxs_error_msg;
break;
case EMLXS_PANIC:
msg2 = &emlxs_panic_msg;
break;
case EMLXS_EVENT:
msg2 = &emlxs_event_msg;
break;
}
/* Check if we are about to overwrite an event entry */
/* Check if this event has not been acquired */
/* Abort exchange */
}
}
}
/* Free the old context buffer since we are about to erase it */
}
/* Initialize */
/* Save the additional info buffer */
"Last message repeated %d time(s).",
/* Set the entry time stamp */
}
/* Get the pointer to the next log entry */
/* Increment and check the next entry index */
}
/* Check if we are about to overwrite an event entry */
/* Check if this event has not been acquired */
/* Abort exchange */
}
}
}
/* Free the old context buffer since we are about to erase it */
}
/* Initialize */
/* Save the additional info buffer */
/* Set the entry time stamp */
/* Check for a new event */
/* Update the event id */
for (i = 0; i < 32; i++) {
if (mask & 0x01) {
break;
}
mask >>= 1;
}
}
if (rxid) {
if (abts_ct_thread = (emlxs_thread_t *)
/*
* The abts_ct_thread will be released by
* the emlxs_abts_ct_thread().
*/
(char *)abts_ct_thread, 0,
}
}
return (0);
} /* emlxs_msg_log() */
static uint32_t
{
case EMLXS_DEBUG:
return (1);
}
break;
case EMLXS_NOTICE:
return (1);
}
break;
case EMLXS_WARNING:
return (1);
}
break;
case EMLXS_ERROR:
return (1);
}
break;
case EMLXS_EVENT:
return (1);
}
#ifdef SAN_DIAG_SUPPORT
return (1);
}
#endif /* SAN_DIAG_SUPPORT */
break;
case EMLXS_PANIC:
return (1);
}
return (0);
} /* emlxs_msg_log_check() */
static uint32_t
{
case EMLXS_DEBUG:
rval |= 2;
}
rval |= 1;
}
break;
case EMLXS_NOTICE:
rval |= 2;
}
rval |= 1;
}
break;
case EMLXS_WARNING:
rval |= 2;
}
rval |= 1;
}
break;
case EMLXS_ERROR:
rval |= 2;
}
rval |= 1;
}
break;
case EMLXS_EVENT:
/* Only print an event if it is being logged internally */
rval |= 2;
}
rval |= 1;
}
}
break;
case EMLXS_PANIC:
default:
rval |= 1;
}
return (rval);
} /* emlxs_msg_print_check() */
void
const char *fmt, ...)
{
#ifdef FMA_SUPPORT
#endif /* FMA_SUPPORT */
char va_str[256];
char msg_str[512];
char *level;
char driver[32];
va_str[0] = 0;
if (fmt) {
}
#ifdef FMA_SUPPORT
/*
* if physical port was not bounded yet.
*/
if (msg->fm_ereport_code) {
}
if (msg->fm_impact_code) {
}
}
#endif /* FMA_SUPPORT */
/* Check if msg should be logged */
/* Log the message */
return;
}
}
/* Check if msg should be printed */
case EMLXS_DEBUG:
level = " DEBUG";
break;
case EMLXS_NOTICE:
level = " NOTICE";
break;
case EMLXS_WARNING:
level = "WARNING";
break;
case EMLXS_ERROR:
level = " ERROR";
break;
case EMLXS_PANIC:
level = " PANIC";
break;
case EMLXS_EVENT:
level = " EVENT";
break;
default:
level = "UNKNOWN";
break;
}
} else {
}
/* Generate the message string */
if (va_str[0] != 0) {
"[%2X.%04X]%s:%7s:%4d: %s (%s)\n", fileno,
va_str);
} else {
"[%2X.%04X]%s:%7s:%4d: %s\n",
}
} else {
if (va_str[0] != 0) {
"[%2X.%04X]%s:%7s:%4d: (%s)\n", fileno,
} else {
"[%2X.%04X]%s:%7s:%4d\n",
}
}
switch (rval) {
case 1: /* MESSAGE LOG ONLY */
/* Message log & console, if system booted in */
/* verbose mode (CE_CONT only) */
break;
case 2: /* CONSOLE ONLY */
break;
case 3: /* CONSOLE AND MESSAGE LOG */
break;
}
}
/* If message was not logged, then free any context buffer provided */
}
return;
} /* emlxs_msg_printf() */
{
uint32_t i;
char *resp_buf;
/* Check if buffer is empty */
/* If so, exit now */
return (1);
}
/* Get current log entry ranges */
/* Get last entry id saved */
/* Check if request is out of current range */
/* if so, exit now */
return (0);
}
/* Get oldest entry id and its index */
/* Check if buffer has already been filled once */
} else { /* Buffer not yet filled */
first = 0;
index = 0;
}
/* Check if requested first message is greater than actual. */
/* If so, adjust for it. */
/* Adjust entry index to first requested message */
}
}
/* Get the total number of messages available for return */
/* Check if requested count is less than actual. If so, adjust it. */
}
/* Fill in the response header */
/* Fill the response buffer */
for (i = 0; i < count; i++) {
/* Increment the response buffer */
/* Increment index */
index = 0;
}
}
return (1);
} /* emlxs_msg_log_get() */
static void
{
char *level;
char buf[256];
char driver[32];
case EMLXS_DEBUG:
level = " DEBUG";
break;
case EMLXS_NOTICE:
level = " NOTICE";
break;
case EMLXS_WARNING:
level = "WARNING";
break;
case EMLXS_ERROR:
level = " ERROR";
break;
case EMLXS_PANIC:
level = " PANIC";
break;
case EMLXS_EVENT:
level = " EVENT";
break;
default:
level = "UNKNOWN";
break;
}
} else {
}
/* Generate the message string */
"%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s (%s)\n",
} else {
"%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s\n", secs,
}
} else {
"%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: (%s)\n",
} else {
"%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d\n",
}
}
} else {
}
return;
} /* emlxs_msg_sprintf() */
void
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
return;
}
if (size > MAX_RSCN_PAYLOAD) {
}
/* Save a copy of the payload for the event log */
return;
}
/*
* Buffer Format:
* word[0] = DID of the RSCN
* word[1] = RSCN Payload
*/
#endif /* DFC_SUPPORT */
return;
} /* emlxs_log_rscn_event() */
void
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
return;
}
if (size > MAX_RSCN_PAYLOAD) {
}
/* Save a copy of the payload for the event log */
if (!(bp =
return;
}
/*
* Buffer Format:
* word[0 - 4] = WWPN of the RSCN
* word[5] = RSCN Payload
*/
#endif /* DFC_SUPPORT */
return;
} /* emlxs_log_vportrscn_event() */
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
return (1);
}
if (size > MAX_CT_PAYLOAD) {
}
/* Save a copy of the payload for the event log */
return (1);
}
/*
* Buffer Format:
* word[0] = RXID tag for outgoing reply to this CT request
* word[1] = CT Payload
*/
return (0);
#else
return (1);
#endif /* DFC_SUPPORT */
} /* emlxs_log_ct_event() */
void
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
/*
* if(!(hba->log_events & EVT_LINK)) { return; }
*/
/* Save a copy of the buffer for the event log */
return;
}
/*
* Buffer Format:
* word[0] = Linkspeed:8
* word[0] = LIP_type:8
* word[0] = resv1:8
* word[0] = resv2:8
* word[1] = dfc_linkinfo_t data
*/
*resv1 = 0;
*resv2 = 0;
*linkspeed = 0;
*liptype = 0;
} else {
/* Set linkspeed */
} else {
}
/* Set LIP type */
}
} else {
}
} else {
}
}
} else {
} else {
}
}
}
#endif /* DFC_SUPPORT */
return;
} /* emlxs_log_link_event() */
void
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
#ifdef DUMP_SUPPORT
/* Schedule a dump thread */
#endif /* DUMP_SUPPORT */
return;
}
/* Save a copy of the buffer for the event log */
return;
}
} else {
size = 0;
}
#else
#ifdef DUMP_SUPPORT
/* Schedule a dump thread */
#endif /* DUMP_SUPPORT */
#endif /* DFC_SUPPORT */
return;
} /* emlxs_log_dump_event() */
extern void
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
#ifdef DUMP_SUPPORT
/* Schedule a dump thread */
#endif /* DUMP_SUPPORT */
return;
}
return;
}
#else /* !DFC_SUPPORT */
#ifdef DUMP_SUPPORT
/* Schedule a dump thread */
#endif /* DUMP_SUPPORT */
#endif /* DFC_SUPPORT */
return;
} /* emlxs_log_temp_event() */
extern void
{
#ifdef DFC_SUPPORT
/* Check if the event is being requested */
return;
}
/* Check if this is a FCOE adapter */
return;
}
size = sizeof (menlo_init_rsp_t);
return;
}
#endif /* DFC_SUPPORT */
return;
} /* emlxs_log_fcoe_event() */
#ifdef SAN_DIAG_SUPPORT
extern void
{
struct sd_plogi_rcv_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_plogi_rcv_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
sizeof (HBA_WWN));
sizeof (HBA_WWN));
return;
} /* emlxs_log_sd_basic_els_event() */
extern void
{
struct sd_prlo_rcv_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_prlo_rcv_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
sizeof (HBA_WWN));
return;
} /* emlxs_log_sd_prlo_event() */
extern void
{
struct sd_lsrjt_rcv_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_lsrjt_rcv_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
sizeof (HBA_WWN));
return;
} /* emlxs_log_sd_lsrjt_event() */
extern void
{
struct sd_pbsy_rcv_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_pbsy_rcv_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
if (remoteport == NULL)
else
{
sizeof (HBA_WWN));
}
return;
} /* emlxs_log_sd_fc_bsy_event() */
extern void
{
struct sd_fcprdchkerr_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_fcprdchkerr_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
sizeof (HBA_WWN));
return;
} /* emlxs_log_sd_rdchk_event() */
extern void
{
struct sd_scsi_generic_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_scsi_generic_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
sizeof (HBA_WWN));
return;
} /* emlxs_log_sd_scsi_event() */
extern void
{
struct sd_scsi_checkcond_v0 *bp;
/* Check if the event is being requested */
return;
size = sizeof (struct sd_scsi_checkcond_v0);
return;
/*
* we are using version field to store subtype, libdfc
* will fix this up before returning data to app.
*/
sizeof (HBA_WWN));
}
#endif /* SAN_DIAG_SUPPORT */
extern void
{
/* ASYNC_STATUS_CN response size */
size = 64;
return;
}
} /* emlxs_log_async_event() */
#ifdef DFC_SUPPORT
extern uint32_t
{
return (DFC_ARG_NULL);
}
max_events = *eventcount;
*eventcount = 0;
/* Check if log is empty */
/* Make sure everything is initialized */
return (0);
}
/* Safety check */
}
/* Account for missed events */
} else {
}
return (0);
}
/* A new event has occurred since last acquisition */
/* Calculate the current buffer boundaries */
/* Get last entry id saved */
/* Get oldest entry id and its index */
/* Check if buffer has already been filled once */
} else { /* Buffer not yet filled */
first = 0;
index = 0;
}
/* Check if requested first event is greater than actual. */
/* If so, adjust for it. */
/* Adjust entry index to first requested message */
}
}
/* Get the total number of new messages */
/* Scan log for next event */
events = 0;
index = 0;
}
break;
}
/* Process this event */
case EVT_LINK:
Reserved[0] = 0;
Reserved[1] = 0;
Reserved[2] = 0;
} else {
if ((linkinfo->a_topology ==
LNK_PUBLIC_LOOP) ||
(linkinfo->a_topology ==
LNK_LOOP)) {
Reserved[0] = 2;
} else {
Reserved[0] = 1;
}
}
break;
case EVT_RSCN:
word[0] & 0xFFFFFF;
/* word[1] is the RSCN payload command */
switch (aid->aff_format) {
case 0: /* Port */
break;
case 1: /* Area */
break;
case 2: /* Domain */
break;
case 3: /* Network */
NPortPage = 0;
break;
}
0;
0;
break;
}
eventinfo++;
events++;
}
}
/* Adjust new count */
} else {
}
/* Return number of events acquired */
*eventcount = events;
return (0);
} /* emlxs_get_dfc_eventinfo() */
{
uint32_t i;
size = 0;
}
/* Get the log file pointer */
/* Calculate the event index */
for (i = 0; i < 32; i++) {
if (mask & 0x01) {
break;
}
mask >>= 1;
}
if (i == 32) {
return (DFC_ARG_INVALID);
}
/* Check if log is empty */
/* Make sure everything is initialized */
} else {
/* Check ranges for safety */
}
}
}
/* Check if no new event has ocurred */
if (!sleep) {
return (0);
}
/* While event is still active and */
/* no new event has been logged */
/* Check if thread was killed by kernel */
if (rc == 0) {
return (0);
}
}
/* If the event is no longer registered then */
/* return immediately */
return (0);
}
}
/* !!! An event has occurred since last_id !!! */
/* Check if event data is not being requested */
if (!size) {
/* If so, then just return the last event id */
return (0);
}
/* !!! The requester wants the next event buffer !!! */
/* Calculate the current buffer boundaries */
/* Get last entry id saved */
/* Get oldest entry id and its index */
/* Check if buffer has already been filled once */
} else { /* Buffer not yet filled */
first = 0;
index = 0;
}
/* Check to see if the buffer has wrapped since the last event */
/* Update last_id to the last known event */
/* Try waiting again if we can */
goto wait_for_event;
}
/* Check if requested first event is greater than actual. */
/* If so, adjust for it. */
/* Adjust entry index to first requested message */
}
}
/* Get the total number of new messages */
/* Scan log for next event */
while (count--) {
index = 0;
}
break;
}
}
/* Check if no new event was found in the current log buffer */
/* This would indicate that the buffer wrapped since that last event */
if (!count) {
/* Update last_id to the last known event */
/* Try waiting again if we can */
goto wait_for_event;
}
/* !!! Next event found !!! */
/* Copy the context buffer to the buffer provided */
}
return (DFC_COPYOUT_ERROR);
}
/* Data has been retrieved by the apps */
}
return (0);
} /* emlxs_get_dfc_event() */
{
/* Get the log file pointer */
return (0);
} /* emlxs_kill_dfc_event() */
#ifdef SAN_DIAG_SUPPORT
{
uint32_t i;
size = 0;
}
/* Get the log file pointer */
/* Calculate the event index */
for (i = 0; i < 32; i++) {
if (mask & 0x01)
break;
mask >>= 1;
}
if (i == 32)
return (DFC_ARG_INVALID);
/* Check if log is empty */
/* Make sure everything is initialized */
} else {
/* Check ranges for safety */
}
/* Check if no new event has ocurred */
if (!sleep) {
return (0);
}
/* While event is active and no new event has been logged */
/* Check if thread was killed by kernel */
if (rc == 0) {
return (0);
}
}
/* If the event is no longer registered then return */
return (0);
}
}
/* !!! An event has occurred since last_id !!! */
/* Check if event data is not being requested */
if (!size) {
/* If so, then just return the last event id */
return (0);
}
/* !!! The requester wants the next event buffer !!! */
/* Calculate the current buffer boundaries */
/* Get last entry id saved */
/* Get oldest entry id and its index */
/* Check if buffer has already been filled once */
} else { /* Buffer not yet filled */
first = 0;
index = 0;
}
/* Check to see if the buffer has wrapped since the last event */
/* Update last_id to the last known event */
/* Try waiting again if we can */
goto wait_for_sd_event;
}
/* if requested first event is greater than actual, adjust for it. */
/* Adjust entry index to first requested message */
}
}
/* Get the total number of new messages */
/* Scan log for next event */
while (count--) {
index = 0;
break;
}
/* Check if no new event was found in the current log buffer */
/* This would indicate that the buffer wrapped since that last event */
if (!count) {
/* Update last_id to the last known event */
/* Try waiting again if we can */
goto wait_for_sd_event;
}
/* !!! Next event found !!! */
/* Copy the context buffer to the buffer provided */
return (DFC_COPYOUT_ERROR);
}
}
return (0);
} /* emlxs_get_sd_event */
#endif /* SAN_DIAG_SUPPORT */
#endif /* DFC_SUPPORT */