1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * MODULE: dapl_evd_dto_callback.c 34 * 35 * PURPOSE: implements DTO callbacks from verbs 36 * 37 * $Id: dapl_evd_dto_callb.c,v 1.17 2003/07/30 18:13:38 hobie16 Exp $ 38 */ 39 40 #include "dapl.h" 41 #include "dapl_evd_util.h" 42 #include "dapl_cno_util.h" 43 #include "dapl_cookie.h" 44 #include "dapl_adapter_util.h" 45 46 /* 47 * dapl_evd_dto_callback 48 * 49 * Input: 50 * hca_handle_in, 51 * cq_handle_in, 52 * user_context_cq_p 53 * 54 * Output: 55 * none 56 * 57 * This is invoked for both DTO and MW bind completions. Strictly 58 * speaking it is an event callback rather than just a DTO callback. 59 * 60 */ 61 62 void 63 dapl_evd_dto_callback( 64 IN ib_hca_handle_t hca_handle, 65 IN ib_cq_handle_t cq_handle, 66 IN void *user_context) 67 { 68 DAPL_EVD *evd_ptr; 69 DAT_RETURN dat_status; 70 DAPL_EVD_STATE state; 71 72 dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK, 73 "dapl_evd_dto_callback(%p, %p, %p)\n", 74 hca_handle, 75 cq_handle, 76 user_context); 77 78 evd_ptr = (DAPL_EVD *) user_context; 79 80 dapl_os_assert(hca_handle == 81 evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle); 82 dapl_os_assert(evd_ptr->ib_cq_handle == cq_handle); 83 dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD); 84 85 /* Read once. */ 86 state = *(volatile DAPL_EVD_STATE *) &evd_ptr->evd_state; 87 88 dapl_dbg_log(DAPL_DBG_TYPE_EVD, 89 "-- dapl_evd_dto_callback: CQ %p, state %x\n", 90 (void *)evd_ptr->ib_cq_handle, 91 state); 92 93 /* 94 * This function does not dequeue from the CQ; only the consumer 95 * can do that. Instead, it wakes up waiters if any exist. 96 * It rearms the completion only if completions should always occur 97 * (specifically if a CNO is associated with the EVD and the 98 * EVD is enabled. 99 */ 100 101 if (state == DAPL_EVD_STATE_WAITED) { 102 /* 103 * If we could, it would be best to avoid this wakeup 104 * (and the context switch) unless the number of events/CQs 105 * waiting for the waiter was its threshold. We don't 106 * currently have the ability to determine that without 107 * dequeueing the events, and we can't do that for 108 * synchronization reasons (racing with the waiter waking 109 * up and dequeuing, sparked by other callbacks). 110 */ 111 112 /* 113 * We don't need to worry about taking the lock for the 114 * wakeup because wakeups are sticky. 115 */ 116 (void) dapl_os_wait_object_wakeup(&evd_ptr->wait_object); 117 } else if (state == DAPL_EVD_STATE_OPEN) { 118 DAPL_CNO *cno = evd_ptr->cno_ptr; 119 if (evd_ptr->evd_enabled && (evd_ptr->cno_ptr != NULL)) { 120 /* 121 * Re-enable callback, *then* trigger. 122 * This guarantees we won't miss any events. 123 */ 124 dat_status = DAPL_NOTIFY(evd_ptr)( 125 evd_ptr->ib_cq_handle, IB_NOTIFY_ON_NEXT_COMP, 0); 126 127 if (DAT_SUCCESS != dat_status) { 128 (void) dapls_evd_post_async_error_event( 129 evd_ptr->header.owner_ia->async_error_evd, 130 DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR, 131 (DAT_IA_HANDLE)evd_ptr->header.owner_ia); 132 } 133 134 dapl_cno_trigger(cno, evd_ptr); 135 } 136 } 137 dapl_dbg_log(DAPL_DBG_TYPE_RTN, "dapl_evd_dto_callback() returns\n"); 138 } 139 140 /* 141 * Local variables: 142 * c-indent-level: 4 143 * c-basic-offset: 4 144 * tab-width: 8 145 * End: 146 */ 147