[DAPL2] Sync with OFED DAPL 2.0.21 src release
[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  * Function Definitions                                              *\r
52  *                                                                   *\r
53  *********************************************************************/\r
54 \r
55 /*\r
56  * dapl_evd_dto_callback\r
57  *\r
58  * Input:\r
59  *      hca_handle_in, \r
60  *      cq_handle_in, \r
61  *      user_context_cq_p\r
62  *\r
63  * Output:\r
64  *      none\r
65  *\r
66  * This is invoked for both DTO and MW bind completions. Strictly \r
67  * speaking it is an event callback rather than just a DTO callback. \r
68  *\r
69  */\r
70 \r
71 void\r
72 dapl_evd_dto_callback(IN ib_hca_handle_t hca_handle,\r
73                       IN ib_cq_handle_t cq_handle, IN void *user_context)\r
74 {\r
75         DAPL_EVD *evd_ptr;\r
76         DAT_RETURN dat_status;\r
77         DAPL_EVD_STATE state;\r
78 \r
79         dapl_dbg_log(DAPL_DBG_TYPE_CALLBACK,\r
80                      "dapl_evd_dto_callback(%p, %p, %p)\n",\r
81                      hca_handle, cq_handle, user_context);\r
82 \r
83         evd_ptr = (DAPL_EVD *) user_context;\r
84         DAPL_CNTR(evd_ptr, DCNT_EVD_DTO_CALLBACK);\r
85 \r
86         dapl_os_assert(hca_handle ==\r
87                        evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle);\r
88         dapl_os_assert(evd_ptr->ib_cq_handle == cq_handle);\r
89         dapl_os_assert(evd_ptr->header.magic == DAPL_MAGIC_EVD);\r
90 \r
91         /* Read once.  */\r
92         state = *(volatile DAPL_EVD_STATE *)&evd_ptr->evd_state;\r
93 \r
94         dapl_dbg_log(DAPL_DBG_TYPE_EVD,\r
95                      "-- dapl_evd_dto_callback: CQ %p, state %x\n",\r
96                      (void *)evd_ptr->ib_cq_handle, state);\r
97 \r
98         /*\r
99          * This function does not dequeue from the CQ; only the consumer\r
100          * can do that. Instead, it wakes up waiters if any exist.\r
101          * It rearms the completion only if completions should always occur\r
102          * (specifically if a CNO is associated with the EVD and the\r
103          * EVD is enabled.\r
104          */\r
105 \r
106         if (state == DAPL_EVD_STATE_WAITED) {\r
107                 /*\r
108                  * If we could, it would be best to avoid this wakeup\r
109                  * (and the context switch) unless the number of events/CQs\r
110                  * waiting for the waiter was its threshold.  We don't\r
111                  * currently have the ability to determine that without\r
112                  * dequeueing the events, and we can't do that for\r
113                  * synchronization reasons (racing with the waiter waking\r
114                  * up and dequeuing, sparked by other callbacks).\r
115                  */\r
116 \r
117                 /*\r
118                  * We don't need to worry about taking the lock for the\r
119                  * wakeup because wakeups are sticky.\r
120                  */\r
121                 dapls_evd_dto_wakeup(evd_ptr);\r
122 \r
123         } else if (state == DAPL_EVD_STATE_OPEN) {\r
124                 DAPL_CNO *cno = evd_ptr->cno_ptr;\r
125                 if (evd_ptr->evd_enabled && (evd_ptr->cno_ptr != NULL)) {\r
126                         /*\r
127                          * Re-enable callback, *then* trigger.\r
128                          * This guarantees we won't miss any events.\r
129                          */\r
130                         dat_status = dapls_ib_completion_notify(hca_handle,\r
131                                                                 evd_ptr,\r
132                                                                 IB_NOTIFY_ON_NEXT_COMP);\r
133 \r
134                         if (DAT_SUCCESS != dat_status) {\r
135                                 (void)dapls_evd_post_async_error_event(evd_ptr->\r
136                                                                        header.\r
137                                                                        owner_ia->\r
138                                                                        async_error_evd,\r
139                                                                        DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR,\r
140                                                                        (DAT_IA_HANDLE)\r
141                                                                        evd_ptr->\r
142                                                                        header.\r
143                                                                        owner_ia);\r
144                         }\r
145 \r
146                         dapl_internal_cno_trigger(cno, evd_ptr);\r
147                 }\r
148         }\r
149         dapl_dbg_log(DAPL_DBG_TYPE_RTN, "dapl_evd_dto_callback () returns\n");\r
150 }\r
151 \r
152 /*\r
153  * Local variables:\r
154  *  c-indent-level: 4\r
155  *  c-basic-offset: 4\r
156  *  tab-width: 8\r
157  * End:\r
158  */\r