/*
* 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 client interfaces of the IBMF.
*/
}
extern ibmf_state_t *ibmf_statep;
extern int ibmf_trace_level;
/* ARGSUSED */
int
{
" ibmf_version = %d, flags = 0x%x, ibmf_impl_featuresp = %p\n",
/* validate client_infop and ibmf_handlep */
(ibmf_impl_features == NULL)) {
"invalid argument, NULL pointer argument");
goto bail;
}
/* check IBMF version */
if (ibmf_version != IBMF_VERSION) {
goto bail;
}
/* check flags validity */
if ((flags & IBMF_REG_FLAG_NO_OFFLOAD) &&
goto bail;
}
/* check client mask and size */
if (status != IBMF_SUCCESS) {
goto bail;
}
/*
* verify the node identified by ir_ci_guid exists and that the
* port ir_port_num is valid.
*/
if (status != IBMF_SUCCESS) {
goto bail;
}
/* get the ci */
if (status != IBMF_SUCCESS) {
"ibmf_register(): %s, guid = 0x%p\n",
return (status);
}
/*
* check if classes and port are already registered for.
*/
if (status != IBMF_SUCCESS) {
/* release ci */
"class and port already registered for or unsupported");
goto bail;
}
/*
* the class is valid, get qp and alloc the client
*/
/* obtain the qp corresponding to the port and classes */
if (status != IBMF_SUCCESS) {
"ibmf_register(): %s, class = 0x%x\n",
return (status);
}
/* alloc the client */
if (status != IBMF_SUCCESS) {
"ibmf_register(): %s, class = 0x%x\n",
return (status);
}
/* initialize the IBMF client context */
/* add the client to the list of clients */
/* increment kstats for number of registered clients */
/* Setup ibmf_handlep -- handle is last allocated clientp */
*ibmf_impl_features = 0;
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
int secs;
"ibmf_handlep = %p, flags = 0x%x\n",
/* check for null ibmf_handlep */
if (ibmf_handlep == NULL) {
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handlep */
goto bail;
}
/* check signature */
goto bail;
}
/*
* Verify the client does not have a receive callback registered.
* If there are messages, give some time for the messages to be
* cleaned up.
*/
secs = 60;
secs > 0) {
secs--;
}
"ibmf_unregister(): %s, flags = 0x%x, recv_cb = 0x%p, "
"msgs_alloced = %d\n",
return (IBMF_BUSY);
}
/* remove the client from the list of clients */
/* release the reference to the qp */
/* and free the client structure */
/* release the ci; this may delete & free the ci structure */
/* decrement kstats for number of registered clients */
*ibmf_handlep = NULL;
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, cb = 0x%p, cb_args = 0x%p, flags = 0x%x\n",
/* check for null ibmf_handlep */
if (ibmf_handle == NULL) {
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* validate ibmf_qp_handle */
IBMF_SUCCESS) {
goto bail;
}
/* check signature */
goto bail;
}
/* store the registered callback in the appropriate context */
if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
/*
* if using the default QP handle, store the callback in
* the client context
*/
/* check if the callback has already been registered */
goto bail;
}
} else {
/*
* if using an alternate QP handle, store the callback in
* the alternate QP context because there can be more than
* one alternate QP associated with a client
*/
/* check if the callback has already been registered */
goto bail;
}
}
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, ibmf_qp_handle = %p, flags = 0x%x\n",
/* check for null ibmf_handlep */
if (ibmf_handle == NULL) {
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* validate ibmf_qp_handle */
IBMF_SUCCESS) {
goto bail;
}
/* check signature */
goto bail;
}
/* remove the registered callback from the appropriate context */
if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
/* check if callback has not been registered */
goto bail;
}
/*
* if an unsolicited MAD just arrived for this
* client, wait for it to be processed
*/
}
/*
* if using the default QP handle, remove the callback from
* the client context
*/
} else {
/* check if callback has not been registered */
goto bail;
}
/*
* if an unsolicited MAD just arrived for this
* client on the alternate QP, wait for it to be processed
*/
}
/*
* if using an alternate QP handle, remove the callback from
* the alternate QP context
*/
}
bail:
if (error) {
}
return (status);
}
int
{
int km_flags;
"ibmf_handle = %p, flags = 0x%x\n",
/* check for null ibmf_handle and ibmf_msgpp */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* check signature */
goto bail;
}
/* validate flag */
goto bail;
}
/* set flags for kmem allocaton */
/* call the internal function to allocate the IBMF message context */
if (status != IBMF_SUCCESS) {
goto bail;
}
/* increment counter and kstats for number of allocated messages */
/* initialize the msg */
bail:
if (error) {
}
return (status);
}
int
{
/* check for null ibmf_handle and ibmf_msgpp */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* check for null message pointer */
if (ibmf_msg_impl == NULL) {
goto bail;
}
/* check if message context flags indicate a busy message */
goto bail;
}
/* Initialize the timer ID holders */
msg_rp_set_id = msg_tr_set_id = 0;
msg_rp_unset_id = msg_tr_unset_id = 0;
/* Clear any timers that are still set */
if (ibmf_msg_impl->im_rp_timeout_id != 0) {
}
if (ibmf_msg_impl->im_tr_timeout_id != 0) {
}
if (ibmf_msg_impl->im_rp_unset_timeout_id != 0) {
}
if (ibmf_msg_impl->im_tr_unset_timeout_id != 0) {
}
/* mark the message context flags to indicate a freed message */
/* cast pointer to client context */
/* check signature */
goto bail;
}
/* Clear the timers */
if (msg_rp_unset_id != 0) {
(void) untimeout(msg_rp_unset_id);
}
if (msg_tr_unset_id != 0) {
(void) untimeout(msg_tr_unset_id);
}
if (msg_rp_set_id != 0) {
(void) untimeout(msg_rp_set_id);
}
if (msg_tr_set_id != 0) {
(void) untimeout(msg_tr_set_id);
}
/* destroy the condition variables */
/* decrement counter and kstats for number of allocated messages */
/* call the internal function to free the message context */
*ibmf_msgpp = NULL;
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, ibmf_qp_handle = %p, flags = 0x%x "
"msgp = 0x%p, retrans = 0x%p\n",
/* check for null ibmf_handle and msgp */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* validate ibmf_qp_handle */
IBMF_SUCCESS) {
goto bail;
}
/* check signature */
goto bail;
}
/*
* Check the validity of the pkey and qkey in the posted packet
* For special QPs do the check for QP1 only
* For the alternate qps, the pkey and qkey should match the
* pkey and qkey maintained in the ibmf cached qp context
*/
if ((ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) &&
"PKey in packet not default PKey");
goto bail;
}
goto bail;
}
} else if (ibmf_qp_handle != IBMF_QP_HANDLE_DEFAULT) {
/* alternate QP context */
"PKey in the QP context");
goto bail;
}
"QKey in the QP context");
goto bail;
}
}
if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
"not provided for special QP");
goto bail;
}
} else {
"not provided for alternate QP");
goto bail;
}
}
/* check if client has freed the message by calling ibmf_free_msg() */
goto bail;
}
/*
* check if the message is already in use in an
* ibmf_msg_transport() call
*/
"Message is being processed by an other thread");
goto bail;
}
/* check for the Directed Route SMP loopback case */
}
/* check for and perform DR loopback on tavor */
if (status != IBMF_SUCCESS) {
goto bail;
}
"ibmf_msg_transport() exit, dr_loopback ok\n");
return (IBMF_SUCCESS);
}
} else {
}
/* initialize the message context */
/* call the internal function to transport the message */
blocking);
if (status != IBMF_SUCCESS) {
goto bail;
}
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, p_key = 0x%x, q_key = 0x%x\n",
/* check for null ibmf_handle and ibmf_qp_handle */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* check signature */
goto bail;
}
/* validate PKey */
if (IBMF_INVALID_PKEY(p_key)) {
goto bail;
}
if (((flags & IBMF_ALT_QP_MAD_NO_RMPP) == 0) &&
((flags & IBMF_ALT_QP_MAD_RMPP) == 0) &&
((flags & IBMF_ALT_QP_RAW_ONLY) == 0)) {
goto bail;
}
/* call the internal function to allocate the alternate QP context */
if (status != IBMF_SUCCESS) {
goto bail;
}
/* initialize the alternate qp context */
if (flags & IBMF_ALT_QP_MAD_NO_RMPP)
if (flags & IBMF_ALT_QP_RAW_ONLY)
if (flags & IBMF_ALT_QP_MAD_RMPP)
else
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, ibmf_qp_handle = %p\n",
/* check for null args */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* validate ibmf_qp_handle */
IBMF_SUCCESS) {
goto bail;
}
/* validate ibmf_qp_handle */
if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
goto bail;
}
/* check signature */
goto bail;
}
/* validate client context handle */
goto bail;
}
/* call the internal function to query the alternate qp */
if (status != IBMF_SUCCESS) {
goto bail;
}
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, ibmf_qp_handle = %p, pkey = 0x%x, "
/* check for null args */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* validate ibmf_qp_handle */
IBMF_SUCCESS) {
goto bail;
}
/* validate ibmf_qp_handle */
if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
goto bail;
}
/* check signature */
goto bail;
}
/* validate PKey */
if (IBMF_INVALID_PKEY(p_key)) {
goto bail;
}
goto bail;
}
/* call the internal function to modify the qp */
if (status != IBMF_SUCCESS) {
goto bail;
}
bail:
if (error) {
}
return (status);
}
/* ARGSUSED */
int
{
"ibmf_handlep = %p, ibmf_qp_handle = %p\n",
/* check for null args */
"invalid argument, NULL pointer argument");
goto bail;
}
/* validate ibmf_handle */
goto bail;
}
/* validate ibmf_qp_handle */
IBMF_SUCCESS) {
goto bail;
}
/* validate ibmf_qp_handle */
if (*ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) {
goto bail;
}
/* check signature */
goto bail;
}
/* validate client context handle */
goto bail;
}
goto bail;
}
if (status != IBMF_SUCCESS) {
goto bail;
}
*ibmf_qp_handle = NULL;
bail:
if (error) {
}
return (status);
}