[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[mirror/winof/.git] / ulp / dapl2 / dapl / common / dapl_evd_dto_callb.c
1 /*\r
2  * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.\r
3  *\r
4  * This Software is licensed under one of the following licenses:\r
5  *\r
6  * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
7  *    available from the Open Source Initiative, see\r
8  *    http://www.opensource.org/licenses/cpl.php.\r
9  *\r
10  * 2) under the terms of the "The BSD License" a copy of which is\r
11  *    available from the Open Source Initiative, see\r
12  *    http://www.opensource.org/licenses/bsd-license.php.\r
13  *\r
14  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
15  *    copy of which is available from the Open Source Initiative, see\r
16  *    http://www.opensource.org/licenses/gpl-license.php.\r
17  *\r
18  * Licensee has the right to choose one of the above licenses.\r
19  *\r
20  * Redistributions of source code must retain the above copyright\r
21  * notice and one of the license notices.\r
22  *\r
23  * Redistributions in binary form must reproduce both the above copyright\r
24  * notice, one of the license notices in the documentation\r
25  * and/or other materials provided with the distribution.\r
26  */\r
27 \r
28 /**********************************************************************\r
29  * \r
30  * MODULE: dapl_evd_dto_callback.c\r
31  *\r
32  * PURPOSE: implements DTO callbacks from verbs\r
33  *\r
34  * $Id:$\r
35  **********************************************************************/\r
36 \r
37 #include "dapl.h"\r
38 #include "dapl_evd_util.h"\r
39 #include "dapl_cno_util.h"\r
40 #include "dapl_cookie.h"\r
41 #include "dapl_adapter_util.h"\r
42 \r
43 /*********************************************************************\r
44  *                                                                   *\r
45  * Function Prototypes                                               *\r
46  *                                                                   *\r
47  *********************************************************************/\r
48 \r
49 \r
50 /*********************************************************************\r
51  *                                                                   *\r
52  * Function Definitions                                              *\r
53  *                                                                   *\r
54  *********************************************************************/\r
55 \r
56 /*\r
57  * dapl_evd_dto_callback\r
58  *\r
59  * Input:\r
60  *      hca_handle_in, \r
61  *      cq_handle_in, \r
62  *      user_context_cq_p\r
63  *\r
64  * Output:\r
65  *      none\r
66  *\r
67  * This is invoked for both DTO and MW bind completions. Strictly \r
68  * speaking it is an event callback rather than just a DTO callback. \r
69  *\r
70  */\r
71 \r
72 void \r
73 dapl_evd_dto_callback (\r
74     IN ib_hca_handle_t  hca_handle, \r
75     IN ib_cq_handle_t   cq_handle, \r
76     IN void*            user_context)\r
77 {\r
78     DAPL_EVD            *evd_ptr;\r
79     DAT_RETURN          dat_status;\r
80     DAPL_EVD_STATE      state;\r
81 \r
82     dapl_dbg_log (DAPL_DBG_TYPE_CALLBACK,\r
83                   "dapl_evd_dto_callback(%p, %p, %p)\n",\r
84                   hca_handle, \r
85                   cq_handle, \r
86                   user_context);\r
87 \r
88     evd_ptr = (DAPL_EVD *) user_context;\r
89     DAPL_CNTR(evd_ptr, DCNT_EVD_DTO_CALLBACK);\r
90 \r
91     dapl_os_assert (hca_handle == evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle);\r
92     dapl_os_assert (evd_ptr->ib_cq_handle == cq_handle);\r
93     dapl_os_assert (evd_ptr->header.magic == DAPL_MAGIC_EVD);\r
94 \r
95     /* Read once.  */\r
96     state = *(volatile DAPL_EVD_STATE *) &evd_ptr->evd_state;\r
97 \r
98     dapl_dbg_log (DAPL_DBG_TYPE_EVD, \r
99                   "-- dapl_evd_dto_callback: CQ %p, state %x\n", \r
100                   (void *)evd_ptr->ib_cq_handle, \r
101                   state);\r
102 \r
103     /*\r
104      * This function does not dequeue from the CQ; only the consumer\r
105      * can do that. Instead, it wakes up waiters if any exist.\r
106      * It rearms the completion only if completions should always occur\r
107      * (specifically if a CNO is associated with the EVD and the\r
108      * EVD is enabled.\r
109      */\r
110        \r
111     if (state == DAPL_EVD_STATE_WAITED)\r
112     {\r
113         /*\r
114          * If we could, it would be best to avoid this wakeup\r
115          * (and the context switch) unless the number of events/CQs\r
116          * waiting for the waiter was its threshold.  We don't\r
117          * currently have the ability to determine that without\r
118          * dequeueing the events, and we can't do that for\r
119          * synchronization reasons (racing with the waiter waking\r
120          * up and dequeuing, sparked by other callbacks).\r
121          */\r
122 \r
123         /*\r
124          * We don't need to worry about taking the lock for the\r
125          * wakeup because wakeups are sticky.\r
126          */\r
127 #ifdef CQ_WAIT_OBJECT\r
128         if (evd_ptr->cq_wait_obj_handle)\r
129             dapls_ib_wait_object_wakeup (evd_ptr->cq_wait_obj_handle);\r
130         else\r
131 #endif\r
132             dapl_os_wait_object_wakeup (&evd_ptr->wait_object);\r
133 \r
134     }\r
135     else if (state == DAPL_EVD_STATE_OPEN)\r
136     {\r
137         DAPL_CNO *cno = evd_ptr->cno_ptr;\r
138         if (evd_ptr->evd_enabled && (evd_ptr->cno_ptr != NULL))\r
139         {\r
140             /*\r
141              * Re-enable callback, *then* trigger.\r
142              * This guarantees we won't miss any events.\r
143              */\r
144             dat_status = dapls_ib_completion_notify (hca_handle, \r
145                                                      evd_ptr,\r
146                                                      IB_NOTIFY_ON_NEXT_COMP);\r
147             \r
148             if ( DAT_SUCCESS != dat_status )\r
149             {\r
150                 (void) dapls_evd_post_async_error_event(\r
151                     evd_ptr->header.owner_ia->async_error_evd,\r
152                     DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR,\r
153                     (DAT_IA_HANDLE) evd_ptr->header.owner_ia);\r
154             }\r
155 \r
156             dapl_internal_cno_trigger(cno, evd_ptr);\r
157         }\r
158     }\r
159     dapl_dbg_log (DAPL_DBG_TYPE_RTN, "dapl_evd_dto_callback () returns\n");\r
160 }\r
161 \r
162 /*\r
163  * Local variables:\r
164  *  c-indent-level: 4\r
165  *  c-basic-offset: 4\r
166  *  tab-width: 8\r
167  * End:\r
168  */\r