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.
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.
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]
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <sys/ib/ibtl/impl/ibtl.h>
29 * These routines implement (most of) the verbs related to
37 static char ibtf_cq
[] = "ibtl_cq";
40 * This file contains code for the TI CQ calls
44 * ibt_alloc_cq_sched() - Reserve CQ scheduling class resources
46 * chan - IBT Channel Handle.
47 * load - Expected CQ load in class, 0 = unspecified
48 * sched_hdl_p - Returned scheduling handle.
51 ibt_alloc_cq_sched(ibt_hca_hdl_t hca_hdl
, ibt_cq_sched_attr_t
*attr
,
52 ibt_sched_hdl_t
*sched_hdl_p
)
54 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_alloc_cq_sched(%p, %p, %p)",
55 hca_hdl
, attr
, sched_hdl_p
);
57 return (IBTL_HCA2CIHCAOPS_P(hca_hdl
)->ibc_alloc_cq_sched(
58 IBTL_HCA2CIHCA(hca_hdl
), attr
, sched_hdl_p
));
63 * ibt_free_cq_sched() - Free CQ scheduling class resources
65 * chan - IBT Channel Handle.
66 * sched_hdl - Scheduling handle returned from ibt_alloc_cq_sched.
67 * load - CQ load being removed.
70 ibt_free_cq_sched(ibt_hca_hdl_t hca_hdl
, ibt_sched_hdl_t sched_hdl
)
72 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_free_cq_sched(%p, %p)",
75 return (IBTL_HCA2CIHCAOPS_P(hca_hdl
)->ibc_free_cq_sched(
76 IBTL_HCA2CIHCA(hca_hdl
), sched_hdl
));
82 * ibt_alloc_cq() - Allocate a completion queue
85 ibt_alloc_cq(ibt_hca_hdl_t hca_hdl
, ibt_cq_attr_t
*cq_attr
,
86 ibt_cq_hdl_t
*ibt_cq_p
, uint32_t *real_size
)
91 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_alloc_cq(%p, %p)",
95 ibt_cq
= kmem_zalloc(sizeof (struct ibtl_cq_s
), KM_SLEEP
);
98 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq
->cq_in_thread
))
99 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq
->cq_ibc_cq_hdl
))
100 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq
->cq_hca
))
102 * Set the following values before creating CI CQ, to avoid race
103 * conditions on async callback.
105 ibt_cq
->cq_hca
= hca_hdl
;
107 ibtl_qp_flow_control_enter();
108 status
= IBTL_HCA2CIHCAOPS_P(hca_hdl
)->ibc_alloc_cq(
109 IBTL_HCA2CIHCA(hca_hdl
), ibt_cq
, cq_attr
, &ibt_cq
->cq_ibc_cq_hdl
,
111 ibtl_qp_flow_control_exit();
113 if (status
!= IBT_SUCCESS
) {
114 IBTF_DPRINTF_L2(ibtf_cq
, "ibt_alloc_cq: "
115 "CI CQ handle allocation failed: status = %d", status
);
116 kmem_free(ibt_cq
, sizeof (struct ibtl_cq_s
));
121 if (cq_attr
->cq_flags
& IBT_CQ_HANDLER_IN_THREAD
) {
122 ibt_cq
->cq_in_thread
= 1;
123 /* We may want additional CQ threads now. */
124 ibtl_another_cq_handler_in_thread();
126 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq
->cq_in_thread
))
127 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq
->cq_ibc_cq_hdl
))
128 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq
->cq_hca
))
130 mutex_init(&ibt_cq
->cq_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
132 /* Update the cq resource count */
133 atomic_inc_32(&hca_hdl
->ha_cq_cnt
);
135 return (IBT_SUCCESS
);
140 * ibt_free_cq() - Free a completion queue
144 ibt_free_cq(ibt_cq_hdl_t ibt_cq
)
147 ibtl_hca_t
*ibt_hca
= ibt_cq
->cq_hca
;
149 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_free_cq(%p)", ibt_cq
);
151 ibtl_free_cq_check(ibt_cq
);
153 status
= ((IBTL_CQ2CIHCAOPS_P(ibt_cq
))->ibc_free_cq
)
154 (IBTL_CQ2CIHCA(ibt_cq
), ibt_cq
->cq_ibc_cq_hdl
);
156 if (status
!= IBT_SUCCESS
) {
157 IBTF_DPRINTF_L2(ibtf_cq
, "ibt_free_cq: "
158 "CI CQ handle de-allocation failed: status = %d", status
);
162 /* mutex_destroy(&ibt_cq->cq_mutex); */
163 ibtl_free_cq_async_check(ibt_cq
);
165 /* Update the cq resource count */
166 atomic_dec_32(&ibt_hca
->ha_cq_cnt
);
173 * ibt_query_cq() - Returns the size of the cq
176 ibt_query_cq(ibt_cq_hdl_t ibt_cq
, uint32_t *entries_p
, uint_t
*count_p
,
177 uint_t
*usec_p
, ibt_cq_handler_id_t
*hid_p
)
179 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_query_cq(%p)", ibt_cq
);
181 return (IBTL_CQ2CIHCAOPS_P(ibt_cq
)->ibc_query_cq(IBTL_CQ2CIHCA(ibt_cq
),
182 ibt_cq
->cq_ibc_cq_hdl
, entries_p
, count_p
, usec_p
, hid_p
));
187 * ibt_resize_cq() - Change the size of a cq.
190 ibt_resize_cq(ibt_cq_hdl_t ibt_cq
, uint32_t new_sz
, uint32_t *real_sz
)
192 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_resize_cq(%p, %d)", ibt_cq
, new_sz
);
194 return (IBTL_CQ2CIHCAOPS_P(ibt_cq
)->ibc_resize_cq(IBTL_CQ2CIHCA(ibt_cq
),
195 ibt_cq
->cq_ibc_cq_hdl
, new_sz
, real_sz
));
199 ibt_modify_cq(ibt_cq_hdl_t ibt_cq
, uint_t count
, uint_t usec
,
200 ibt_cq_handler_id_t hid
)
202 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_modify_cq(%p, %d, %d, %d)", ibt_cq
, count
,
205 return (IBTL_CQ2CIHCAOPS_P(ibt_cq
)->ibc_modify_cq(IBTL_CQ2CIHCA(ibt_cq
),
206 ibt_cq
->cq_ibc_cq_hdl
, count
, usec
, hid
));
212 * Poll the specified CQ for a work request (WR) completion. If a CQ
213 * contains a completed WR, the completed WR at the head of the CQ is
216 * ibt_cq The CQ handle.
218 * work_completions An array of work completions.
220 * num_wc Size of the Work completion array. The
221 * requested number of completions.
223 * num_polled The actual number of completions returned.
227 ibt_poll_cq(ibt_cq_hdl_t ibt_cq
, ibt_wc_t
*work_completions
, uint_t num_wc
,
230 IBTF_DPRINTF_L4(ibtf_cq
, "ibt_poll_cq(%p)", ibt_cq
);
232 return (IBTL_CQ2CIHCAOPS_P(ibt_cq
)->ibc_poll_cq(IBTL_CQ2CIHCA(ibt_cq
),
233 ibt_cq
->cq_ibc_cq_hdl
, work_completions
, num_wc
, num_polled
));
236 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_cq_s::cq_clnt_private
))
239 * ibt_set_cq_private - Sets the private data on a given CQ
241 * ibt_cq The ibt_cq_hdl_t of the allocated CQ.
242 * clnt_private The client private data.
245 ibt_set_cq_private(ibt_cq_hdl_t ibt_cq
, void *clnt_private
)
247 ibt_cq
->cq_clnt_private
= clnt_private
;
252 * ibt_get_cq_private - Retrieves the private data for a given CQ
254 * ibt_cq The ibt_cq_hdl_t of the allocated CQ.
257 ibt_get_cq_private(ibt_cq_hdl_t ibt_cq
)
259 return (ibt_cq
->cq_clnt_private
);
263 * ibt_query_cq_handler_id - Retrieves the attributes of a cq_handler_id.
266 ibt_query_cq_handler_id(ibt_hca_hdl_t hca_hdl
,
267 ibt_cq_handler_id_t hid
, ibt_cq_handler_attr_t
*attrs
)
269 IBTF_DPRINTF_L3(ibtf_cq
, "ibt_query_cq_handler(%p, %d, %p)",
270 hca_hdl
, hid
, attrs
);
272 return (IBTL_HCA2CIHCAOPS_P(hca_hdl
)->ibc_query_cq_handler_id(
273 IBTL_HCA2CIHCA(hca_hdl
), hid
, attrs
));