dapl_evd_dto_callb.c revision 9517:b4839b0aa7a4
167754Smsmith/* 267754Smsmith * CDDL HEADER START 367754Smsmith * 467754Smsmith * The contents of this file are subject to the terms of the 567754Smsmith * Common Development and Distribution License (the "License"). 667754Smsmith * You may not use this file except in compliance with the License. 767754Smsmith * 867754Smsmith * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 967754Smsmith * or http://www.opensolaris.org/os/licensing. 1067754Smsmith * See the License for the specific language governing permissions 11193267Sjkim * and limitations under the License. 1270243Smsmith * 1367754Smsmith * When distributing Covered Code, include this CDDL HEADER in each 1467754Smsmith * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1567754Smsmith * If applicable, add the following below this CDDL HEADER, with the 1667754Smsmith * fields enclosed by brackets "[]" replaced with your own identifying 1767754Smsmith * information: Portions Copyright [yyyy] [name of copyright owner] 1867754Smsmith * 1967754Smsmith * CDDL HEADER END 2067754Smsmith */ 2167754Smsmith 2267754Smsmith/* 2367754Smsmith * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved. 2467754Smsmith */ 2567754Smsmith 2667754Smsmith/* 2767754Smsmith * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2867754Smsmith * Use is subject to license terms. 2967754Smsmith */ 3067754Smsmith 3167754Smsmith/* 3267754Smsmith * 3367754Smsmith * MODULE: dapl_evd_dto_callback.c 3467754Smsmith * 3567754Smsmith * PURPOSE: implements DTO callbacks from verbs 3667754Smsmith * 3767754Smsmith * $Id: dapl_evd_dto_callb.c,v 1.17 2003/07/30 18:13:38 hobie16 Exp $ 3867754Smsmith */ 3967754Smsmith 4067754Smsmith#include "dapl.h" 4167754Smsmith#include "dapl_evd_util.h" 4267754Smsmith#include "dapl_cno_util.h" 4367754Smsmith#include "dapl_cookie.h" 4467754Smsmith#include "dapl_adapter_util.h" 4567754Smsmith 4667754Smsmith/* 4767754Smsmith * dapl_evd_dto_callback 4867754Smsmith * 4967754Smsmith * Input: 5067754Smsmith * hca_handle_in, 5167754Smsmith * cq_handle_in, 5267754Smsmith * user_context_cq_p 5367754Smsmith * 5467754Smsmith * Output: 5567754Smsmith * none 5667754Smsmith * 5767754Smsmith * This is invoked for both DTO and MW bind completions. Strictly 5867754Smsmith * speaking it is an event callback rather than just a DTO callback. 5967754Smsmith * 6067754Smsmith */ 6167754Smsmith 6267754Smsmithvoid 6367754Smsmithdapl_evd_dto_callback( 6467754Smsmith IN ib_hca_handle_t hca_handle, 6567754Smsmith IN ib_cq_handle_t cq_handle, 6667754Smsmith IN void *user_context) 6767754Smsmith{ 6867754Smsmith DAPL_EVD *evd_ptr; 6967754Smsmith DAT_RETURN dat_status; 7067754Smsmith DAPL_EVD_STATE state; 7167754Smsmith 7267754Smsmith dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK, 7367754Smsmith "dapl_evd_dto_callback(%p, %p, %p)\n", 7467754Smsmith hca_handle, 7567754Smsmith cq_handle, 7667754Smsmith user_context); 7767754Smsmith 7867754Smsmith evd_ptr = (DAPL_EVD *) user_context; 7967754Smsmith 8067754Smsmith dapl_os_assert(hca_handle == 8167754Smsmith evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle); 8267754Smsmith dapl_os_assert(evd_ptr->ib_cq_handle == cq_handle); 8367754Smsmith dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD); 8467754Smsmith 8567754Smsmith /* Read once. */ 8667754Smsmith state = *(volatile DAPL_EVD_STATE *) &evd_ptr->evd_state; 8767754Smsmith 8867754Smsmith dapl_dbg_log(DAPL_DBG_TYPE_EVD, 8967754Smsmith "-- dapl_evd_dto_callback: CQ %p, state %x\n", 9067754Smsmith (void *)evd_ptr->ib_cq_handle, 9167754Smsmith state); 9267754Smsmith 9367754Smsmith /* 9467754Smsmith * This function does not dequeue from the CQ; only the consumer 9567754Smsmith * can do that. Instead, it wakes up waiters if any exist. 9667754Smsmith * It rearms the completion only if completions should always occur 9767754Smsmith * (specifically if a CNO is associated with the EVD and the 9867754Smsmith * EVD is enabled. 9967754Smsmith */ 10067754Smsmith 10167754Smsmith if (state == DAPL_EVD_STATE_WAITED) { 10267754Smsmith /* 10367754Smsmith * If we could, it would be best to avoid this wakeup 10467754Smsmith * (and the context switch) unless the number of events/CQs 10567754Smsmith * waiting for the waiter was its threshold. We don't 10667754Smsmith * currently have the ability to determine that without 10767754Smsmith * dequeueing the events, and we can't do that for 10867754Smsmith * synchronization reasons (racing with the waiter waking 10967754Smsmith * up and dequeuing, sparked by other callbacks). 11067754Smsmith */ 11167754Smsmith 11267754Smsmith /* 11367754Smsmith * We don't need to worry about taking the lock for the 11467754Smsmith * wakeup because wakeups are sticky. 11567754Smsmith */ 11667754Smsmith (void) dapl_os_wait_object_wakeup(&evd_ptr->wait_object); 11767754Smsmith } else if (state == DAPL_EVD_STATE_OPEN) { 11867754Smsmith DAPL_CNO *cno = evd_ptr->cno_ptr; 119193341Sjkim if (evd_ptr->evd_enabled && (evd_ptr->cno_ptr != NULL)) { 120193341Sjkim /* 121193341Sjkim * Re-enable callback, *then* trigger. 122193341Sjkim * This guarantees we won't miss any events. 123193341Sjkim */ 12467754Smsmith dat_status = DAPL_NOTIFY(evd_ptr)( 12577424Smsmith evd_ptr->ib_cq_handle, IB_NOTIFY_ON_NEXT_COMP, 0); 12691116Smsmith 12767754Smsmith if (DAT_SUCCESS != dat_status) { 128151937Sjkim (void) dapls_evd_post_async_error_event( 12967754Smsmith evd_ptr->header.owner_ia->async_error_evd, 130151937Sjkim DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR, 131151937Sjkim (DAT_IA_HANDLE)evd_ptr->header.owner_ia); 132151937Sjkim } 133151937Sjkim 134151937Sjkim dapl_cno_trigger(cno, evd_ptr); 135151937Sjkim } 136151937Sjkim } 137151937Sjkim dapl_dbg_log(DAPL_DBG_TYPE_RTN, "dapl_evd_dto_callback() returns\n"); 138151937Sjkim} 139151937Sjkim 140151937Sjkim/* 141151937Sjkim * Local variables: 142151937Sjkim * c-indent-level: 4 143151937Sjkim * c-basic-offset: 4 144167802Sjkim * tab-width: 8 145167802Sjkim * End: 146167802Sjkim */ 147167802Sjkim