ibmf_msg.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file implements the IBMF message related functions.
*/
extern int ibmf_trace_level;
/*
* ibmf_i_client_add_msg():
* Add the message to the client message list
*/
void
{
"ibmf_i_client_add_msg(): clientp = 0x%p, msgp = 0x%p\n",
/*
* If this is a termination message, add the message to
* the termination message list else add the message
* to the regular message list.
*/
/* Put the message on the list */
} else {
}
} else {
/*
* Increment the counter and kstats for active messages
*/
/* Put the message on the list */
} else {
}
}
/* Set the message flags to indicate the message is on the list */
"ibmf_i_client_add_msg() exit\n");
}
/*
* ibmf_i_client_rem_msg():
* Remove the message from the client's message list
* The refcnt will hold the message reference count at the time
* the message was removed from the message list. Any packets
* arriving after this point for the message will be dropped.
* The message reference count is used by the threads processing
* the message to decide which one should notify the client
* (the one that decrements the reference count to zero).
*/
void
{
"ibmf_i_client_rem_msg(): clientp = 0x%p, msgp = 0x%p\n",
/*
* If this is a termination message, remove the message from
* the termination message list else remove the message
* from the regular message list.
*/
break;
}
else
else
} else {
/*
* Decrement the counter and kstats for active messages
*/
break;
}
else
else
}
/* Save away the message reference count and clear the list flag */
"ibmf_i_client_rem_msg() exit\n");
}
/*
* ibmf_i_find_msg():
* Walk the client message list for the message corresponding to
* the parameters specified
* The msg_list parameter should be either IBMF_REG_MSG_LIST
* or IBMF_TERM_MSG_LIST for the termination message list.
*/
{
int msg_found;
"ibmf_i_find_msg(): clientp = 0x%p, tid = 0x%p, mgmt_class = 0x%x, "
if (msg_list == IBMF_REG_MSG_LIST)
else
/*
* Look for a transaction (message) context that matches the
* transaction ID, gid or lid, and management class of the
* incoming packet.
*
* If the client decides to do a non-rmpp or rmpp send only,
* despite expecting a response, then the response should check
* if the message context for the send still exists.
* If it does, it should be skipped.
*/
/* first match gid */
continue;
}
} else {
"ibmf_i_find_msg(): %s, msgp = 0x%p, tid = 0x%p, "
"remote_lid = 0x%x, mgmt_class = 0x%x\n",
/* first match lid */
continue;
}
}
/* next match tid and class */
continue;
}
/*
* For unsolicited transactions, the message is found
* if the method matches, but,
* If the response is an ACK, and the transaction is
* in RMPP receiver mode, then skip this message.
*/
((rmpp_ctx->rmpp_state ==
(rmpp_ctx->rmpp_state ==
/* Continue if ACK packet */
continue;
}
}
if (msgimplp->im_trans_state_flags ==
r_method) {
break;
}
}
}
/*
* if this was an unsequenced, non-RMPP transaction there should
* be no incoming packets
*/
if ((!(msgimplp->im_transp_op_flags &
(!(msgimplp->im_transp_op_flags &
continue;
}
/*
* if this is a sequenced transaction,
* (the send and response may or may not be RMPP)
* and the method of the incoming MAD is the same as the
* method in the send message context with the response bit
* set then this message matches.
*/
break;
}
}
/*
* if this is an RMPP SEND transaction there should only
* be ACK, STOP, and ABORTS RMPP packets.
* The response data packets would have been detected in
* the check above.
*/
/*
* If non-sequenced, then there should be
* no DATA packets incoming for this transaction
*/
if (!(msgimplp->im_transp_op_flags &
/* Continue if DATA packet */
msgimplp =
continue;
}
}
/* Skip if R_Method does not match */
if ((rmpp_ctx->rmpp_state ==
(rmpp_ctx->rmpp_state ==
/* Continue if DATA packet */
msgimplp =
continue;
}
/*
* Continue if method does not match
* Ignore response bit during match.
*/
if ((msgbufp->im_bufs_mad_hdr->
R_Method & MAD_METHOD_MASK) !=
(r_method & MAD_METHOD_MASK)) {
continue;
}
}
/* Skip if R_Method does not match */
if ((rmpp_ctx->rmpp_state ==
(rmpp_ctx->rmpp_state ==
/* Continue if ACK packet */
msgimplp =
continue;
}
/* Continue if method does not match */
if (msgbufp->im_bufs_mad_hdr->
continue;
}
}
}
}
/*
* For a sequenced non-RMPP transaction, if the
* of the incoming MAD and the message context are the
* same, then the MAD is likely to be a new request from
* the remote entity, so skip this message.
*/
/* Continue if method is the same */
if (msgbufp->im_bufs_mad_hdr->
continue;
}
}
/* everything matches, found the correct message */
break;
}
"ibmf_i_find_msg(): %s, msgp = 0x%p, ref_cnt = 0x%d\n",
}
return (msgimplp);
}
/*
* ibmf_i_find_msg_client():
* Walk the client message list to find the specified message
*/
{
"ibmf_i_find_msg_client(): clientp = 0x%p, msgp = 0x%p\n",
/* grab the mutex */
if (inc_refcnt == B_TRUE)
"ibmf_i_find_msg_client(): %s, msgp = 0x%p, "
"ref_cnt = 0x%d\n",
break;
}
}
/*
* If not found on the regular message list,
* look in the termination list.
*/
/* grab the mutex */
if (inc_refcnt == B_TRUE)
"ibmf_i_find_msg_client(): %s, "
"msgp = 0x%p, ref_cnt = 0x%d\n", tnf_string,
msg, "Found message. Inc ref count",
break;
}
}
}
"ibmf_i_find_msg_client() exit\n");
return (found);
}
/*
* ibmf_setup_recvbuf_on_error():
*
* This function is used to set up the receive buffers to provide
* a context for sending ABORT MADs in cases where the protocol
* fails before the receive buffers have been setup. This can happen
* if the initial receive MAD has a bad version, or an unexpected
* segment number, for example.
* We allocate IBMF_MAD_SIZE memory as we only need the information
* stored in the MAD header and the class header to be able to send
* the ABORT.
*/
int
{
/*
* Allocate enough memory for the MAD headers only.
*/
"recv buf mem allocation failure");
"ibmf_setup_recvbuf_on_error() exit\n");
return (IBMF_NO_RESOURCES);
}
/* Get the class header size and offset */
&cl_hdr_off);
/* copy the MAD and class header */
/* offset of the class header */
/* initialize class header pointer */
if (cl_hdr_sz == 0) {
} else {
}
/* Set the class header length */
/* offset of the class data */
/* initialize data area pointer */
return (IBMF_SUCCESS);
}