/*
* 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
*/
/*
*/
/*
* This file implements the timer setup and timeout handling functions.
*/
extern int ibmf_trace_level;
/*
* ibmf_i_set_timer():
* Set the timer to the response or transaction time interval
*/
void
{
"timer_type = 0x%x, func_cb = 0x%p\n",
if (type == IBMF_RESP_TIMER) {
/*
* The response timer interval is the sum of the IBA
* defined RespTimeValue (Vol. 1, Section 13.4.6.2.2),
* and the round trip time value. Both values are determined
* by the IBMF client and passed in the retrans_rtv and
* retrans_rttv fields respectively, when calling
* ibmf_msg_transport()
*/
"resp_time %x round trip time %x\n",
} else if (type == IBMF_TRANS_TIMER) {
/*
* if payload was not specified use IB spec default
* of 40 seconds
*/
"ibmf_i_set_timer: %s, interval = %ld\n",
"payload size unknown. Using default trans_to",
} else {
/*
* if payload was specified, use a variation of IB
* spec equation (13.6.3.2) that accounts for average
* window size
*/
IBMF_RMPP_DEFAULT_WIN_SZ * 4 *
"ibmf_i_set_timer: %s, num_pkts = %d, rttv ="
" %x, window_size = %d, interval = %ld\n",
}
/*
* Use the client specified transaction timeout value if
* smaller than the calculated value
*/
"ibmf_i_set_timer: %s, new_interval = %ld\n",
}
}
}
/*
* ibmf_i_unset_timer():
* Unset the timer
*/
void
{
if (type == IBMF_RESP_TIMER) {
if (msgimplp->im_rp_timeout_id != 0) {
msgimplp->im_rp_timeout_id = 0;
}
} else if (type == IBMF_TRANS_TIMER) {
if (msgimplp->im_tr_timeout_id != 0) {
msgimplp->im_tr_timeout_id = 0;
}
}
}
/*
* ibmf_i_recv_timeout:
*
* Perform "receive" timeout processing for the message.
* This timeout handler is only used in RMPP processing.
*/
void
{
int msg_flags;
int status;
"ibmf_i_recv_timeout(): resetting id time %llx\n",
/*
* If the message has been marked unitialized or done
* release the message mutex and return
*/
"Message marked for removal, return without processing "
"recv timeout",
return;
}
/*
* Unset the response and trans timers if they haven't fired (unlikely)
*/
/* Perform timeout processing for the RMPP transaction */
"RMPP context is Receiver Active, sending ABORT T2L");
IBMF_RMPP_STATUS_T2L, 0, 0, IBMF_NO_BLOCK);
if (status != IBMF_SUCCESS) {
"RMPP ABORT send failed");
}
"RMPP context is Receiver Active, terminating transaction");
"RMPP context is Receiver Terminate, "
"terminating transaction");
}
/*
* Save the transaction state flags and the timeout IDs
* before releasing the mutex as they may be changed after that.
*/
"ibmf_i_recv_timeout(): %s, msgp = 0x%p, refcnt = %d\n", tnf_string,
/*
* If the transaction flags indicate a completed transaction,
* notify the client
*/
if (msg_flags & IBMF_TRANS_STATE_FLAG_DONE) {
/* Remove the message from the client's message list */
/*
* Notify the client if the message reference count is zero.
* At this point, we know that the transaction is done and
* the message has been removed from the client's message list.
* So, we only need to make sure the reference count is zero
* before notifying the client.
*/
if (ref_cnt == 0) {
/*
* If the message is a termination message,
* free it at this time.
*/
"ibmf_i_recv_timeout(): freeing terminate "
/* free up the UD destination resource */
}
/* Free the receive buffer */
/* destroy the message mutex */
/* Free the termination message context */
/*
* Decrease the "messages allocated" count
* so that an ibmf_unregister() can succeed
* for this client.
*/
} else {
"ibmf_i_recv_timeout(): calling "
}
}
}
"ibmf_i_recv_timeout() exit\n");
}
/*
* ibmf_i_send_timeout:
*
* Perform "send" timeout processing for the message.
* This timeout handler is used in non-RMPP and RMPP processing.
*/
void
{
int msg_flags;
int status;
"ibmf_i_send_timeout_client(): msgp = 0x%p mgt_class = 0x%x "
"local lid 0x%x remote lid 0x%x remote q# 0x%x\n",
/*
* If the message has been marked uninitialized or done, release the
* message mutex and return
*/
"Message is done, return without processing send timeout",
return;
}
/*
* If the timer fired, but the corresponding MAD was received before
* we got to this point in the timeout code, then do nothing in the
* timeout handler and return
*/
(msgimplp->im_rp_timeout_id == 0)) {
"Message not in undefined state, return without processing "
"send timeout",
return;
}
/* Clear the response timer */
if (msgimplp->im_rp_timeout_id != 0)
/*
* Non-RMPP send transaction timeout processing
*/
/*
* We use the RMPP context to store the retry count even if
* the response does not use RMPP
*/
if (rmpp_ctx->rmpp_retry_cnt <
"ibmf_i_send_timeout(): %s, msgp = 0x%p, "
"retry_cnt = %d, max_retries = %d\n",
if (status == IBMF_SUCCESS) {
"ibmf_i_send_timeout(): %s, msgp = 0x%p\n",
return;
}
"ibmf_i_send_timeout(): %s, msgp = 0x%p, "
"Retry send failed; terminating transaction",
} else {
"Not RMPP SEND, terminate transaction with "
"IBMF_TRANS_TIMEOUT");
}
/*
* If we are in receive RMPP mode, then an ABORT should
* be sent after the required number of retries.
*/
if (status != IBMF_SUCCESS) {
"ibmf_i_send_timeout(): %s\n", tnf_string,
msg, "RMPP ABORT send failed");
}
}
/* Notify the client if the transaction is done */
if (msg_flags & IBMF_TRANS_STATE_FLAG_DONE) {
"ibmf_i_send_timeout(): %s, msgp = 0x%p\n",
/* Remove the message from the client's message list */
/*
* Notify the client if the message reference count is
* zero. At this point, we know that the transaction is
* done and the message has been removed from the
* client's message list. So, we need to be sure the
* reference count is zero before notifying the client.
*/
if (ref_cnt == 0) {
}
}
return;
}
"ibmf_i_send_timeout(): %s, msgp = 0x%p, retry_cnt = %d, "
/* RMPP send transaction timeout processing */
"Maximum retries done, sending ABORT TMR");
IBMF_RMPP_STATUS_TMR, 0, 0, IBMF_NO_BLOCK);
if (status != IBMF_SUCCESS) {
"RMPP ABORT send failed");
}
"Maximum retries done, terminate transaction with "
"IBMF_TRANS_TIMEOUT");
} else {
"RMPP context is Sender Active, Resending window");
/*
* resend the window
*/
} else if (rmpp_ctx->rmpp_state ==
"RMPP context is Sender Terminate, sending ACK");
/* send ACK */
"ibmf_i_send_timeout(): setting timer %d %p\n",
/* set response timer */
}
}
if (msg_flags & IBMF_TRANS_STATE_FLAG_DONE) {
/* Remove the message from the client's message list */
/*
* Notify the client if the message reference count is zero.
* At this point, we know that the transaction is done and
* the message has been removed from the client's message list.
* So, we only need to make sure the reference count is zero
* before notifying the client.
*/
if (ref_cnt == 0) {
}
}
}
void
{
int msg_flags;
"ibmf_i_err_terminate_timeout_client(): msgp = 0x%p\n",
/*
* If the message has been marked uninitialized or done, release the
* message mutex and return
*/
"ibmf_i_err_terminate_timeout(): %s, msgp = 0x%p\n",
"processing error terminate timeout",
return;
}
/* Clear the response timer */
if (msgimplp->im_rp_timeout_id != 0)
msgimplp->im_rp_timeout_id = 0;
/* Mark the transaction as terminated */
if (msg_flags & IBMF_TRANS_STATE_FLAG_DONE) {
"ibmf_i_err_terminate_timeout(): %s, msgp = 0x%p\n",
/* Remove the message from the client's message list */
/*
* Notify the client if the message reference count is zero.
* At this point, we know that the transaction is done and
* the message has been removed from the client's message list.
* So, we only need to make sure the reference count is zero
* before notifying the client.
*/
if (ref_cnt == 0) {
/*
* If the message is a termination message,
* free it at this time.
*/
IBMF_TNF_TRACE, "",
"ibmf_i_recv_timeout(): freeing terminate "
/* free up the UD destination resource */
}
/* Free the receive buffer */
/* destroy the message mutex */
/* Free the termination message context */
/*
* Decrease the "messages allocated" count
* so that an ibmf_unregister() can succeed
* for this client.
*/
} else {
IBMF_TNF_TRACE, "",
"ibmf_i_recv_timeout(): calling "
}
}
}
"ibmf_i_err_terminate_timeout() exit\n");
}