10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*9130SEiji.Ota@Sun.COM * Common Development and Distribution License (the "License").
6*9130SEiji.Ota@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*9130SEiji.Ota@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * This file implements the callback handler logic common to send and receive
280Sstevel@tonic-gate * handling in IBMF.
290Sstevel@tonic-gate */
300Sstevel@tonic-gate
310Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf_impl.h>
320Sstevel@tonic-gate
330Sstevel@tonic-gate extern int ibmf_trace_level;
340Sstevel@tonic-gate extern ibmf_state_t *ibmf_statep;
350Sstevel@tonic-gate extern void ibmf_saa_impl_ibt_async_handler(ibt_async_code_t code,
360Sstevel@tonic-gate ibt_async_event_t *event);
370Sstevel@tonic-gate
380Sstevel@tonic-gate static void ibmf_i_process_completion(ibmf_ci_t *cip, ibt_wc_t *wcp);
390Sstevel@tonic-gate static void ibmf_i_callback_clients(ib_guid_t hca_guid,
400Sstevel@tonic-gate ibmf_async_event_t evt);
410Sstevel@tonic-gate
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate * ibmf_ibt_async_handler():
440Sstevel@tonic-gate * This function handles asynchronous events detected by the
450Sstevel@tonic-gate * IBT framework.
460Sstevel@tonic-gate */
470Sstevel@tonic-gate /* ARGSUSED */
480Sstevel@tonic-gate void
ibmf_ibt_async_handler(void * clnt_private,ibt_hca_hdl_t hca_hdl,ibt_async_code_t code,ibt_async_event_t * event)490Sstevel@tonic-gate ibmf_ibt_async_handler(void *clnt_private, ibt_hca_hdl_t hca_hdl,
500Sstevel@tonic-gate ibt_async_code_t code, ibt_async_event_t *event)
510Sstevel@tonic-gate {
520Sstevel@tonic-gate ibmf_ci_t *cip;
530Sstevel@tonic-gate
540Sstevel@tonic-gate IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_ibt_async_handler_start,
550Sstevel@tonic-gate IBMF_TNF_TRACE, "",
560Sstevel@tonic-gate "ibmf_ibt_async_handler: Code %x HCA GUID %016" PRIx64 " Port %d\n",
570Sstevel@tonic-gate tnf_uint, code, code, tnf_opaque, hca_guid, event->ev_hca_guid,
580Sstevel@tonic-gate tnf_uint, port, event->ev_port);
590Sstevel@tonic-gate
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate * let ibmf_saa know events first hand
620Sstevel@tonic-gate */
630Sstevel@tonic-gate ibmf_saa_impl_ibt_async_handler(code, event);
640Sstevel@tonic-gate
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate * call client callbacks and then fail if ANY client remains.
670Sstevel@tonic-gate */
680Sstevel@tonic-gate if (code == IBT_HCA_DETACH_EVENT) {
690Sstevel@tonic-gate
700Sstevel@tonic-gate ibmf_i_callback_clients(event->ev_hca_guid, IBMF_CI_OFFLINE);
710Sstevel@tonic-gate
720Sstevel@tonic-gate mutex_enter(&ibmf_statep->ibmf_mutex);
730Sstevel@tonic-gate cip = ibmf_statep->ibmf_ci_list;
740Sstevel@tonic-gate
750Sstevel@tonic-gate while (cip != NULL) {
760Sstevel@tonic-gate mutex_enter(&cip->ci_mutex);
770Sstevel@tonic-gate
780Sstevel@tonic-gate if (cip->ci_node_guid == event->ev_hca_guid) {
790Sstevel@tonic-gate
800Sstevel@tonic-gate mutex_exit(&cip->ci_mutex);
810Sstevel@tonic-gate break;
820Sstevel@tonic-gate }
830Sstevel@tonic-gate
840Sstevel@tonic-gate mutex_exit(&cip->ci_mutex);
850Sstevel@tonic-gate cip = cip->ci_next;
860Sstevel@tonic-gate }
870Sstevel@tonic-gate
880Sstevel@tonic-gate if (cip != NULL) {
890Sstevel@tonic-gate /*
900Sstevel@tonic-gate * found the right ci, check
910Sstevel@tonic-gate * if any clients are still registered
920Sstevel@tonic-gate * (Note that if we found the ci, chances are that
930Sstevel@tonic-gate * it was not released).
940Sstevel@tonic-gate */
950Sstevel@tonic-gate mutex_enter(&cip->ci_clients_mutex);
960Sstevel@tonic-gate
970Sstevel@tonic-gate if (cip->ci_clients != NULL) {
980Sstevel@tonic-gate
990Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG,
1000Sstevel@tonic-gate DPRINT_L1, ibmf_ibt_async_handler_err,
1010Sstevel@tonic-gate IBMF_TNF_TRACE, "",
1020Sstevel@tonic-gate "%s, returning failure\n",
1030Sstevel@tonic-gate tnf_string, msg,
1040Sstevel@tonic-gate "ibmf_ibt_async_handler: Found "
1050Sstevel@tonic-gate "clients still registered.");
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate mutex_exit(&cip->ci_clients_mutex);
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate mutex_exit(&ibmf_statep->ibmf_mutex);
1100Sstevel@tonic-gate } else if (code == IBT_EVENT_SQD) {
1110Sstevel@tonic-gate ibmf_ci_t *cip;
1120Sstevel@tonic-gate ibt_qp_hdl_t qphdl = (ibt_qp_hdl_t)event->ev_chan_hdl;
1130Sstevel@tonic-gate ibmf_alt_qp_t *altqpp;
1140Sstevel@tonic-gate boolean_t found = B_FALSE;
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate mutex_enter(&ibmf_statep->ibmf_mutex);
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate cip = ibmf_statep->ibmf_ci_list;
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate * An SQD event is received. We match the QP handle provided
1220Sstevel@tonic-gate * with all the alternate QP handles maintained on the lists
1230Sstevel@tonic-gate * of all the CI contexts. If a match is found, we wake
1240Sstevel@tonic-gate * up the thread waiting in ibmf_modify_qp().
1250Sstevel@tonic-gate */
1260Sstevel@tonic-gate while (cip != NULL) {
1270Sstevel@tonic-gate mutex_enter(&cip->ci_mutex);
1280Sstevel@tonic-gate altqpp = cip->ci_alt_qp_list;
1290Sstevel@tonic-gate while (altqpp != NULL) {
1300Sstevel@tonic-gate if (altqpp->isq_qp_handle == qphdl) {
1310Sstevel@tonic-gate mutex_enter(&altqpp->isq_mutex);
1320Sstevel@tonic-gate cv_signal(&altqpp->isq_sqd_cv);
1330Sstevel@tonic-gate mutex_exit(&altqpp->isq_mutex);
1340Sstevel@tonic-gate found = B_TRUE;
1350Sstevel@tonic-gate break;
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate altqpp = altqpp->isq_next;
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate mutex_exit(&cip->ci_mutex);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate if (found)
1420Sstevel@tonic-gate break;
1430Sstevel@tonic-gate cip = cip->ci_next;
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate mutex_exit(&ibmf_statep->ibmf_mutex);
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate if (!found)
1490Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG,
1500Sstevel@tonic-gate DPRINT_L1, ibmf_ibt_async_handler_err,
1510Sstevel@tonic-gate IBMF_TNF_TRACE, "", "%s, ignoring event\n",
1520Sstevel@tonic-gate tnf_string, msg, "ibmf_ibt_async_handler: SQD "
1530Sstevel@tonic-gate "event for unknown QP received");
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_ibt_async_handler_end,
1570Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_ibt_async_handler: exit.\n");
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate /*
1610Sstevel@tonic-gate * ibmf_i_callback_clients():
1620Sstevel@tonic-gate * Finds the ci given in parameter.
1630Sstevel@tonic-gate * Calls the client callbacks with the event given in parameter.
1640Sstevel@tonic-gate * Note that client callbacks are called with all ibmf mutexes unlocked.
1650Sstevel@tonic-gate */
1660Sstevel@tonic-gate static void
ibmf_i_callback_clients(ib_guid_t hca_guid,ibmf_async_event_t evt)1670Sstevel@tonic-gate ibmf_i_callback_clients(ib_guid_t hca_guid, ibmf_async_event_t evt)
1680Sstevel@tonic-gate {
1690Sstevel@tonic-gate ibmf_ci_t *cip;
1700Sstevel@tonic-gate ibmf_client_t *clientp;
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate int nclients = 0;
1730Sstevel@tonic-gate ibmf_async_event_cb_t *cb_array = NULL;
1740Sstevel@tonic-gate void **cb_args_array = NULL;
1750Sstevel@tonic-gate ibmf_handle_t *client_array = NULL;
1760Sstevel@tonic-gate int iclient;
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_i_callback_clients_start,
1790Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_i_callback_clients() enter\n");
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate /* find ci */
1820Sstevel@tonic-gate mutex_enter(&ibmf_statep->ibmf_mutex);
1830Sstevel@tonic-gate cip = ibmf_statep->ibmf_ci_list;
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate while (cip != NULL) {
1860Sstevel@tonic-gate mutex_enter(&cip->ci_mutex);
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate if (cip->ci_node_guid == hca_guid) {
1890Sstevel@tonic-gate mutex_exit(&cip->ci_mutex);
1900Sstevel@tonic-gate break;
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate mutex_exit(&cip->ci_mutex);
1940Sstevel@tonic-gate cip = cip->ci_next;
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate if (cip == NULL) {
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
2000Sstevel@tonic-gate ibmf_i_callback_clients, IBMF_TNF_TRACE, "",
2010Sstevel@tonic-gate "ibmf_i_callback_clients: "
2020Sstevel@tonic-gate "ci = %016" PRIx64 "NOT found.\n",
2030Sstevel@tonic-gate tnf_opaque, hca_guid, hca_guid);
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate mutex_exit(&ibmf_statep->ibmf_mutex);
2060Sstevel@tonic-gate goto bail;
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate /* found the right ci, count clients */
2100Sstevel@tonic-gate mutex_enter(&cip->ci_clients_mutex);
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate /* empty counting loop */
2130Sstevel@tonic-gate for (clientp = cip->ci_clients, nclients = 0; clientp != NULL;
214*9130SEiji.Ota@Sun.COM clientp = clientp->ic_next, nclients++)
215*9130SEiji.Ota@Sun.COM ;
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L3,
2180Sstevel@tonic-gate ibmf_i_callback_clients, IBMF_TNF_TRACE, "",
2190Sstevel@tonic-gate "ibmf_i_callback_clients: found %d clients, "
2200Sstevel@tonic-gate "on ci = %016" PRIx64 "\n",
2210Sstevel@tonic-gate tnf_int, nclients, nclients,
2220Sstevel@tonic-gate tnf_opaque, hca_guid, hca_guid);
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate /* no clients? bail */
2250Sstevel@tonic-gate if (nclients == 0) {
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate mutex_exit(&cip->ci_clients_mutex);
2280Sstevel@tonic-gate mutex_exit(&ibmf_statep->ibmf_mutex);
2290Sstevel@tonic-gate goto bail;
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate /* allocate callback, args, and client arrays */
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate cb_array = kmem_zalloc(
235*9130SEiji.Ota@Sun.COM nclients * sizeof (ibmf_async_event_cb_t), KM_NOSLEEP);
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate cb_args_array = kmem_zalloc(
238*9130SEiji.Ota@Sun.COM nclients * sizeof (void*), KM_NOSLEEP);
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate client_array = kmem_zalloc(
241*9130SEiji.Ota@Sun.COM nclients * sizeof (ibmf_handle_t), KM_NOSLEEP);
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate if (cb_array == NULL || cb_args_array == NULL ||
2440Sstevel@tonic-gate client_array == NULL) {
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
2470Sstevel@tonic-gate ibmf_i_callback_clients_err, IBMF_TNF_ERROR, "",
2480Sstevel@tonic-gate "ibmf_i_callback_clients: %s\n",
2490Sstevel@tonic-gate tnf_string, msg, "could not allocate memory for "
2500Sstevel@tonic-gate "callback arrays");
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate mutex_exit(&cip->ci_clients_mutex);
2530Sstevel@tonic-gate mutex_exit(&ibmf_statep->ibmf_mutex);
2540Sstevel@tonic-gate goto bail;
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate /* build callback list */
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate for (clientp = cip->ci_clients, iclient = 0;
2600Sstevel@tonic-gate clientp != NULL;
2610Sstevel@tonic-gate clientp = clientp->ic_next, iclient++) {
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate cb_array[iclient] = clientp->ic_async_cb;
2640Sstevel@tonic-gate cb_args_array[iclient] = clientp->ic_async_cb_arg;
2650Sstevel@tonic-gate client_array[iclient] = (ibmf_handle_t)clientp;
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate mutex_exit(&cip->ci_clients_mutex);
2690Sstevel@tonic-gate mutex_exit(&ibmf_statep->ibmf_mutex);
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate /*
2720Sstevel@tonic-gate * All mutex unlocked, call back clients
2730Sstevel@tonic-gate */
2740Sstevel@tonic-gate for (iclient = 0; iclient < nclients; iclient++) {
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L3,
2770Sstevel@tonic-gate ibmf_i_callback_clients, IBMF_TNF_TRACE, "",
2780Sstevel@tonic-gate "ibmf_i_callback_clients: client %d"
2790Sstevel@tonic-gate ", handle = %016" PRIx64
2800Sstevel@tonic-gate ", callback = %016" PRIx64 ", args = %016" PRIx64 "\n",
2810Sstevel@tonic-gate tnf_int, iclient, iclient,
2820Sstevel@tonic-gate tnf_opaque, handle, client_array[iclient],
2830Sstevel@tonic-gate tnf_opaque, cb_ptr, cb_array[iclient],
2840Sstevel@tonic-gate tnf_opaque, args_ptr, cb_args_array[iclient]);
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate if (cb_array[iclient] != NULL)
2870Sstevel@tonic-gate cb_array[iclient](client_array[iclient],
2880Sstevel@tonic-gate cb_args_array[iclient], evt);
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate bail:
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate if (cb_array != NULL)
2940Sstevel@tonic-gate kmem_free(cb_array, nclients * sizeof (ibmf_async_event_cb_t));
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate if (cb_args_array != NULL)
2970Sstevel@tonic-gate kmem_free(cb_args_array, nclients * sizeof (void*));
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate if (client_array != NULL)
3000Sstevel@tonic-gate kmem_free(client_array, nclients * sizeof (ibmf_handle_t));
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_i_callback_clients_end,
3030Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_i_callback_clients: exit.\n");
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate /*
3070Sstevel@tonic-gate * ibmf_i_mad_completions():
3080Sstevel@tonic-gate * Check for a completion entry on the specified CQ and process it
3090Sstevel@tonic-gate */
3100Sstevel@tonic-gate void
ibmf_i_mad_completions(ibt_cq_hdl_t cq_handle,void * arg)3110Sstevel@tonic-gate ibmf_i_mad_completions(ibt_cq_hdl_t cq_handle, void *arg)
3120Sstevel@tonic-gate {
3130Sstevel@tonic-gate ibt_wc_t cqe;
3140Sstevel@tonic-gate ibt_status_t status;
3150Sstevel@tonic-gate ibmf_ci_t *ibmf_cip;
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4,
3180Sstevel@tonic-gate ibmf_i_mad_completions_start, IBMF_TNF_TRACE, "",
3190Sstevel@tonic-gate "ibmf_i_mad_completions() enter, cq_hdl = %p\n",
3200Sstevel@tonic-gate tnf_opaque, cq_handle, cq_handle);
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate ibmf_cip = arg;
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate ASSERT(ibmf_cip != NULL);
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate /*
3270Sstevel@tonic-gate * Pull a completion and process it
3280Sstevel@tonic-gate */
3290Sstevel@tonic-gate for (;;) {
3300Sstevel@tonic-gate status = ibt_poll_cq(cq_handle, &cqe, 1, NULL);
3310Sstevel@tonic-gate ASSERT(status != IBT_CQ_HDL_INVALID &&
3320Sstevel@tonic-gate status != IBT_HCA_HDL_INVALID);
333*9130SEiji.Ota@Sun.COM /*
334*9130SEiji.Ota@Sun.COM * Check if the status is IBT_SUCCESS or IBT_CQ_EMPTY
335*9130SEiji.Ota@Sun.COM * either which can return from ibt_poll_cq(). In other
336*9130SEiji.Ota@Sun.COM * cases, log the status for the further investigation.
337*9130SEiji.Ota@Sun.COM */
338*9130SEiji.Ota@Sun.COM if (status != IBT_SUCCESS) {
339*9130SEiji.Ota@Sun.COM if (status != IBT_CQ_EMPTY) {
340*9130SEiji.Ota@Sun.COM cmn_err(CE_NOTE, "!ibmf_i_mad_completions got "
341*9130SEiji.Ota@Sun.COM "an error status (0x%x) from ibt_poll_cq.",
342*9130SEiji.Ota@Sun.COM status);
343*9130SEiji.Ota@Sun.COM }
3440Sstevel@tonic-gate break;
345*9130SEiji.Ota@Sun.COM }
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate /* process the completion */
3480Sstevel@tonic-gate ibmf_i_process_completion(ibmf_cip, &cqe);
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate (void) ibt_enable_cq_notify(cq_handle, IBT_NEXT_COMPLETION);
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate /*
3540Sstevel@tonic-gate * Look for more completions just in case some came in before
3550Sstevel@tonic-gate * we were able to reenable CQ notification
3560Sstevel@tonic-gate */
3570Sstevel@tonic-gate for (;;) {
3580Sstevel@tonic-gate status = ibt_poll_cq(cq_handle, &cqe, 1, NULL);
3590Sstevel@tonic-gate ASSERT(status != IBT_CQ_HDL_INVALID &&
3600Sstevel@tonic-gate status != IBT_HCA_HDL_INVALID);
361*9130SEiji.Ota@Sun.COM /*
362*9130SEiji.Ota@Sun.COM * Check if the status is IBT_SUCCESS or IBT_CQ_EMPTY
363*9130SEiji.Ota@Sun.COM * either which can return from ibt_poll_cq(). In other
364*9130SEiji.Ota@Sun.COM * cases, log the status for the further investigation.
365*9130SEiji.Ota@Sun.COM */
366*9130SEiji.Ota@Sun.COM if (status != IBT_SUCCESS) {
367*9130SEiji.Ota@Sun.COM if (status != IBT_CQ_EMPTY) {
368*9130SEiji.Ota@Sun.COM cmn_err(CE_NOTE, "!ibmf_i_mad_completions got "
369*9130SEiji.Ota@Sun.COM "an error status (0x%x) from ibt_poll_cq.",
370*9130SEiji.Ota@Sun.COM status);
371*9130SEiji.Ota@Sun.COM }
3720Sstevel@tonic-gate break;
373*9130SEiji.Ota@Sun.COM }
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate /* process the completion */
3760Sstevel@tonic-gate ibmf_i_process_completion(ibmf_cip, &cqe);
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_mad_completions_end,
3800Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_i_mad_completions() exit\n");
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate
3830Sstevel@tonic-gate /*
3840Sstevel@tonic-gate * ibmf_i_process_completion():
3850Sstevel@tonic-gate * Process the send or receive completion
3860Sstevel@tonic-gate */
3870Sstevel@tonic-gate static void
ibmf_i_process_completion(ibmf_ci_t * cip,ibt_wc_t * wcp)3880Sstevel@tonic-gate ibmf_i_process_completion(ibmf_ci_t *cip, ibt_wc_t *wcp)
3890Sstevel@tonic-gate {
3900Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4,
3910Sstevel@tonic-gate ibmf_i_process_completion_start, IBMF_TNF_TRACE, "",
3920Sstevel@tonic-gate "ibmf_i_process_completion() enter, cip = %p, wcp = %p\n",
3930Sstevel@tonic-gate tnf_opaque, cip, cip, tnf_opaque, wcp, wcp);
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate if (IBMF_IS_RECV_WR_ID(wcp->wc_id) == B_TRUE) {
3960Sstevel@tonic-gate /* completion from a receive queue */
3970Sstevel@tonic-gate ibmf_i_handle_recv_completion(cip, wcp);
3980Sstevel@tonic-gate } else {
3990Sstevel@tonic-gate /* completion from a send queue */
4000Sstevel@tonic-gate ibmf_i_handle_send_completion(cip, wcp);
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_process_completion_end,
4040Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_i_process_completion() exit\n");
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate #ifdef DEBUG
4080Sstevel@tonic-gate static int ibmf_i_dump_mad_size = 0x40;
4090Sstevel@tonic-gate static int ibmf_i_dump_wcp_enable = 0;
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate /* ARGSUSED */
4120Sstevel@tonic-gate void
ibmf_i_dump_wcp(ibmf_ci_t * cip,ibt_wc_t * wcp,ibmf_recv_wqe_t * recv_wqep)4130Sstevel@tonic-gate ibmf_i_dump_wcp(ibmf_ci_t *cip, ibt_wc_t *wcp, ibmf_recv_wqe_t *recv_wqep)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate uchar_t *ptr;
4160Sstevel@tonic-gate char buf[256], *sptr;
4170Sstevel@tonic-gate int i, j;
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate if (ibmf_i_dump_wcp_enable == 0)
4200Sstevel@tonic-gate return;
4210Sstevel@tonic-gate
4220Sstevel@tonic-gate printf("wcp: sender lid %x port num %x path bits %x qp %x sl %x\n",
4230Sstevel@tonic-gate wcp->wc_slid, recv_wqep->recv_port_num, wcp->wc_path_bits,
4240Sstevel@tonic-gate wcp->wc_qpn, wcp->wc_sl);
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate ptr = (uchar_t *)((uintptr_t)recv_wqep->recv_mem +
4270Sstevel@tonic-gate sizeof (ib_grh_t));
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate printf("mad:\n");
4300Sstevel@tonic-gate /* first print multiples of 16bytes */
4310Sstevel@tonic-gate for (i = ibmf_i_dump_mad_size; i >= 16; i -= 16) {
4320Sstevel@tonic-gate for (sptr = buf, j = 0; j < 16; j++) {
4330Sstevel@tonic-gate (void) sprintf(sptr, "%02x ", *ptr++);
4340Sstevel@tonic-gate sptr += 3; /* 2 digits + space */
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate printf("%s\n", buf);
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate /* print the rest */
4390Sstevel@tonic-gate if (i < 16) {
4400Sstevel@tonic-gate for (sptr = buf, j = 0; j < i; j++) {
4410Sstevel@tonic-gate (void) sprintf(sptr, "%02x ", *ptr++);
4420Sstevel@tonic-gate sptr += 3; /* 2 digits + space */
4430Sstevel@tonic-gate }
4440Sstevel@tonic-gate printf("%s\n", buf);
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate #endif /* DEBUG */
448