1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * ibmf_saa.c
31*0Sstevel@tonic-gate *
32*0Sstevel@tonic-gate */
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf_saa_impl.h>
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gate /*
37*0Sstevel@tonic-gate * As a primitive error checking scheme, the first 4 bytes of the client state
38*0Sstevel@tonic-gate * have a well-known pattern. We write this pattern during session_open, make
39*0Sstevel@tonic-gate * sure all subsequent calls still have this pattern in the client state, and
40*0Sstevel@tonic-gate * clear the pattern on session_close. Clients could still run into trouble
41*0Sstevel@tonic-gate * providing a bad handle since we don't check a known list of handles. But
42*0Sstevel@tonic-gate * this mechanism will protect against making ibmf_saa calls after the session
43*0Sstevel@tonic-gate * has been closed.
44*0Sstevel@tonic-gate */
45*0Sstevel@tonic-gate #define IBMF_SAA_SET_CLIENT_SIGNATURE(clientp) { \
46*0Sstevel@tonic-gate (clientp)->saa_client_sig = (void *)0xACEDFACE; \
47*0Sstevel@tonic-gate }
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gate #define IBMF_SAA_VERIFY_CLIENT_SIGNATURE(clientp) \
50*0Sstevel@tonic-gate (((clientp) != NULL && (clientp)->saa_client_sig == \
51*0Sstevel@tonic-gate (void *)0xACEDFACE) ? B_TRUE: B_FALSE)
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gate #define IBMF_SAA_CLEAR_CLIENT_SIGNATURE(clientp) { \
54*0Sstevel@tonic-gate (clientp)->saa_client_sig = 0; \
55*0Sstevel@tonic-gate }
56*0Sstevel@tonic-gate
57*0Sstevel@tonic-gate /* Global Sa_access State Pointer */
58*0Sstevel@tonic-gate extern saa_state_t *saa_statep;
59*0Sstevel@tonic-gate extern int ibmf_trace_level;
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gate /*
62*0Sstevel@tonic-gate * Locking scheme:
63*0Sstevel@tonic-gate * ibmf_saa maintains a linked list of port entries. Each element of the list
64*0Sstevel@tonic-gate * contains information about a certain port. There may be multiple clients
65*0Sstevel@tonic-gate * associated with each of these entries. The list is synchronized with a state
66*0Sstevel@tonic-gate * port_list_mutex. Each of the entries has their own individual mutex. When
67*0Sstevel@tonic-gate * adding a new port entry to the mutex the client, with the list mutex, marks
68*0Sstevel@tonic-gate * the port as registering, adds the port, and releases the list mutex.
69*0Sstevel@tonic-gate * Subsequent clients aquire the list mutex, find the port, acquire the port
70*0Sstevel@tonic-gate * mutex, release the list mutex, and wait if the port is marked as registering.
71*0Sstevel@tonic-gate * Clients should never try to acquire the list mutex when they have a port
72*0Sstevel@tonic-gate * mutex.
73*0Sstevel@tonic-gate */
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gate /*
76*0Sstevel@tonic-gate * ibmf_sa_session_open():
77*0Sstevel@tonic-gate *
78*0Sstevel@tonic-gate * Before using the ibmf_saa interface, consumers should register with the
79*0Sstevel@tonic-gate * ibmf_saa interface by calling ibmf_sa_session_open(). Upon a successful
80*0Sstevel@tonic-gate * registration, a handle is returned for use in subsequent interaction with the
81*0Sstevel@tonic-gate * ibmf_saa interface; this handle is also provided as an argument to subnet
82*0Sstevel@tonic-gate * event notification function.
83*0Sstevel@tonic-gate *
84*0Sstevel@tonic-gate * Consumers can register to be notified of subnet events such as GID
85*0Sstevel@tonic-gate * being available/unavailable. Clients which provide a non-NULL event args
86*0Sstevel@tonic-gate * structure will have the is_event_callback function called when an event is
87*0Sstevel@tonic-gate * received or there is a failure in subscribing for events. This callback may
88*0Sstevel@tonic-gate * be generated before the ibmf_sa_session_open() call returns.
89*0Sstevel@tonic-gate *
90*0Sstevel@tonic-gate * This interface blocks allocating memory, but not waiting for any packet
91*0Sstevel@tonic-gate * responses.
92*0Sstevel@tonic-gate *
93*0Sstevel@tonic-gate * Arguments:
94*0Sstevel@tonic-gate * port_guid - GUID of the port.
95*0Sstevel@tonic-gate * event_args - subnet event registration details
96*0Sstevel@tonic-gate * sm_key - only filled in if the consumer is an SM
97*0Sstevel@tonic-gate * ibmf_version - version of the interface (IBMF_VERSION)
98*0Sstevel@tonic-gate * flags - unused
99*0Sstevel@tonic-gate *
100*0Sstevel@tonic-gate * Output Arguments:
101*0Sstevel@tonic-gate * ibmf_sa_handle - pointer to ibmf_saa_handle to be used in future calls
102*0Sstevel@tonic-gate *
103*0Sstevel@tonic-gate * Return values:
104*0Sstevel@tonic-gate * IBMF_SUCCESS - registration succeeded
105*0Sstevel@tonic-gate * IBMF_BAD_PORT - registration failed; active port not found
106*0Sstevel@tonic-gate * IBMF_BAD_PORT_STATE - registration failed; port found but not active or
107*0Sstevel@tonic-gate * previous registration failed
108*0Sstevel@tonic-gate * IBMF_NO_MEMORY - registration failed; could not allocate memory
109*0Sstevel@tonic-gate * IBMF_NO_RESOURCES - registration failed due to a resource issue
110*0Sstevel@tonic-gate * IBMF_BUSY - registration failed; too many clients registered
111*0Sstevel@tonic-gate * for this port
112*0Sstevel@tonic-gate * IBMF_TRANSPORT_FAILURE - failure with underlying transport framework
113*0Sstevel@tonic-gate * IBMF_INVALID_ARG - ibmf_saa_handle arg was NULL
114*0Sstevel@tonic-gate *
115*0Sstevel@tonic-gate * The ibmf_saa module maintains a linked list of ports which it knows about.
116*0Sstevel@tonic-gate * For each port, a reference count is kept. When the first client for a
117*0Sstevel@tonic-gate * port registers with ibmf_saa, ibmf_saa registers with ibmf.
118*0Sstevel@tonic-gate * The reference count checking must be serialized to
119*0Sstevel@tonic-gate * ensure that only one client modifies the reference count at a time.
120*0Sstevel@tonic-gate * When a client determines that it is responsible for registering it
121*0Sstevel@tonic-gate * sets the state field to "registering" in the port. Clients registering with
122*0Sstevel@tonic-gate * sa_acess will cv_wait on this field before modifying the reference count.
123*0Sstevel@tonic-gate * Unregistering clients do not need to wait on this field since no one else
124*0Sstevel@tonic-gate * will be registering while they are completing (the port's ref count will
125*0Sstevel@tonic-gate * be greater than 0).
126*0Sstevel@tonic-gate * If ibmf registration fails, the entry is set to "invalid"; we decrement
127*0Sstevel@tonic-gate * the reference count that we just incremented.
128*0Sstevel@tonic-gate *
129*0Sstevel@tonic-gate * WARNING: after decrementing the reference count, NO further access to
130*0Sstevel@tonic-gate * the entry should be performed in the same thread, because invalid entries
131*0Sstevel@tonic-gate * with ref counts of 0 are purged.
132*0Sstevel@tonic-gate */
133*0Sstevel@tonic-gate /* ARGSUSED */
134*0Sstevel@tonic-gate int
ibmf_sa_session_open(ib_guid_t port_guid,ib_smkey_t sm_key,ibmf_saa_subnet_event_args_t * event_args,uint_t ibmf_version,uint_t flags,ibmf_saa_handle_t * ibmf_saa_handle)135*0Sstevel@tonic-gate ibmf_sa_session_open(ib_guid_t port_guid, ib_smkey_t sm_key,
136*0Sstevel@tonic-gate ibmf_saa_subnet_event_args_t *event_args, uint_t ibmf_version,
137*0Sstevel@tonic-gate uint_t flags, ibmf_saa_handle_t *ibmf_saa_handle)
138*0Sstevel@tonic-gate {
139*0Sstevel@tonic-gate saa_port_t *saa_portp = NULL;
140*0Sstevel@tonic-gate int status = IBMF_SUCCESS;
141*0Sstevel@tonic-gate saa_client_data_t *saa_client = NULL;
142*0Sstevel@tonic-gate
143*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
144*0Sstevel@tonic-gate ibmf_sa_session_open_start, IBMF_TNF_TRACE, "",
145*0Sstevel@tonic-gate "ibmf_sa_session_open() enter\n");
146*0Sstevel@tonic-gate
147*0Sstevel@tonic-gate if (ibmf_version != IBMF_VERSION) {
148*0Sstevel@tonic-gate
149*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_NODEBUG, DPRINT_L1,
150*0Sstevel@tonic-gate ibmf_sa_session_open_err, IBMF_TNF_ERROR, "",
151*0Sstevel@tonic-gate "ibmf_sa_session_open: Bad Version\n");
152*0Sstevel@tonic-gate
153*0Sstevel@tonic-gate status = IBMF_BAD_VERSION;
154*0Sstevel@tonic-gate goto bail;
155*0Sstevel@tonic-gate }
156*0Sstevel@tonic-gate
157*0Sstevel@tonic-gate if (ibmf_saa_handle == NULL) {
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_NODEBUG, DPRINT_L1,
160*0Sstevel@tonic-gate ibmf_sa_session_open_err, IBMF_TNF_ERROR, "",
161*0Sstevel@tonic-gate "ibmf_sa_session_open: invalid argument, null pointer\n");
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gate status = IBMF_INVALID_ARG;
164*0Sstevel@tonic-gate goto bail;
165*0Sstevel@tonic-gate }
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L3,
168*0Sstevel@tonic-gate ibmf_sa_session_open, IBMF_TNF_TRACE, "",
169*0Sstevel@tonic-gate "ibmf_sa_session_open: %s, guid = %016" PRIx64 ", prefix = %016"
170*0Sstevel@tonic-gate PRIx64 "\n", tnf_string, msg, "opening session",
171*0Sstevel@tonic-gate tnf_opaque, guid, port_guid);
172*0Sstevel@tonic-gate
173*0Sstevel@tonic-gate /*
174*0Sstevel@tonic-gate * Find a valid entry matching the port guid
175*0Sstevel@tonic-gate * Refcount is immediately incremented
176*0Sstevel@tonic-gate */
177*0Sstevel@tonic-gate
178*0Sstevel@tonic-gate /* acquire list mutex (and keep it locked until after creation) */
179*0Sstevel@tonic-gate mutex_enter(&saa_statep->saa_port_list_mutex);
180*0Sstevel@tonic-gate
181*0Sstevel@tonic-gate saa_portp = saa_statep->saa_port_list;
182*0Sstevel@tonic-gate while (saa_portp != NULL) {
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate if (saa_portp->saa_pt_port_guid == port_guid &&
185*0Sstevel@tonic-gate ibmf_saa_is_valid(saa_portp, B_TRUE) == B_TRUE) {
186*0Sstevel@tonic-gate
187*0Sstevel@tonic-gate break;
188*0Sstevel@tonic-gate }
189*0Sstevel@tonic-gate saa_portp = saa_portp->next;
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate if (saa_portp != NULL) {
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
195*0Sstevel@tonic-gate ibmf_sa_session_open, IBMF_TNF_TRACE, "",
196*0Sstevel@tonic-gate "ibmf_sa_session_open(): %s\n",
197*0Sstevel@tonic-gate tnf_string, msg, "port exists\n");
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate /* release list mutex */
200*0Sstevel@tonic-gate mutex_exit(&saa_statep->saa_port_list_mutex);
201*0Sstevel@tonic-gate
202*0Sstevel@tonic-gate /*
203*0Sstevel@tonic-gate * now add client to existing port
204*0Sstevel@tonic-gate * (will wait till end of ibmf registering)
205*0Sstevel@tonic-gate * Note that the state may have changed in the meantime...
206*0Sstevel@tonic-gate */
207*0Sstevel@tonic-gate status = ibmf_saa_impl_add_client(saa_portp);
208*0Sstevel@tonic-gate
209*0Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
210*0Sstevel@tonic-gate
211*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
212*0Sstevel@tonic-gate ibmf_sa_session_open_err, IBMF_TNF_ERROR, "",
213*0Sstevel@tonic-gate "ibmf_sa_session_open: %s, status = %d\n",
214*0Sstevel@tonic-gate tnf_string, msg, "ibmf_saa_impl_add_client()"
215*0Sstevel@tonic-gate " failed", tnf_int, status, status);
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate goto bail;
218*0Sstevel@tonic-gate }
219*0Sstevel@tonic-gate } else {
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate /* create minimal port entry, non blocking */
222*0Sstevel@tonic-gate status = ibmf_saa_impl_create_port(port_guid, &saa_portp);
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
225*0Sstevel@tonic-gate
226*0Sstevel@tonic-gate /* release list mutex */
227*0Sstevel@tonic-gate mutex_exit(&saa_statep->saa_port_list_mutex);
228*0Sstevel@tonic-gate
229*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
230*0Sstevel@tonic-gate ibmf_sa_session_open_err, IBMF_TNF_ERROR, "",
231*0Sstevel@tonic-gate "ibmf_sa_session_open: %s, status = %d\n",
232*0Sstevel@tonic-gate tnf_string, msg, "ibmf_saa_impl_create_port()"
233*0Sstevel@tonic-gate " failed", tnf_int, status, status);
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate goto bail;
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate /* link to list */
239*0Sstevel@tonic-gate saa_portp->next = saa_statep->saa_port_list;
240*0Sstevel@tonic-gate saa_statep->saa_port_list = saa_portp;
241*0Sstevel@tonic-gate
242*0Sstevel@tonic-gate /*
243*0Sstevel@tonic-gate * release the list mutex since we now have the minimum amount
244*0Sstevel@tonic-gate * of port data initialized to prevent subsequent clients from
245*0Sstevel@tonic-gate * continuing with registration (they will cv_wait on registe-
246*0Sstevel@tonic-gate * -ring state). We don't want to hold the list mutex since
247*0Sstevel@tonic-gate * other ports may need it and since we're about to make calls
248*0Sstevel@tonic-gate * to functions which may block.
249*0Sstevel@tonic-gate *
250*0Sstevel@tonic-gate * We do not need the port registering mutex since clients will
251*0Sstevel@tonic-gate * not proceed while saa_pt_state ==
252*0Sstevel@tonic-gate * IBMF_SAA_PORT_STATE_REGISTERING.
253*0Sstevel@tonic-gate */
254*0Sstevel@tonic-gate mutex_exit(&saa_statep->saa_port_list_mutex);
255*0Sstevel@tonic-gate
256*0Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(saa_portp->saa_pt_kstatp))
257*0Sstevel@tonic-gate
258*0Sstevel@tonic-gate status = ibmf_saa_impl_init_kstats(saa_portp);
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
263*0Sstevel@tonic-gate ibmf_sa_session_open_err, IBMF_TNF_ERROR, "",
264*0Sstevel@tonic-gate "ibmf_sa_session_open: %s, status = %d\n",
265*0Sstevel@tonic-gate tnf_string, msg, "could not initialize kstats",
266*0Sstevel@tonic-gate tnf_int, status, status);
267*0Sstevel@tonic-gate
268*0Sstevel@tonic-gate ibmf_saa_impl_register_failed(saa_portp);
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate goto bail;
271*0Sstevel@tonic-gate }
272*0Sstevel@tonic-gate
273*0Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*saa_portp))
274*0Sstevel@tonic-gate
275*0Sstevel@tonic-gate status = ibmf_saa_impl_register_port(saa_portp);
276*0Sstevel@tonic-gate
277*0Sstevel@tonic-gate if (status != IBMF_SUCCESS) {
278*0Sstevel@tonic-gate
279*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
280*0Sstevel@tonic-gate ibmf_sa_session_open_err, IBMF_TNF_ERROR, "",
281*0Sstevel@tonic-gate "ibmf_sa_session_open: %s, ibmf_status = %d\n",
282*0Sstevel@tonic-gate tnf_string, msg,
283*0Sstevel@tonic-gate "ibmf_saa_impl_register_port failed",
284*0Sstevel@tonic-gate tnf_int, ibmf_status, status);
285*0Sstevel@tonic-gate
286*0Sstevel@tonic-gate ibmf_saa_impl_register_failed(saa_portp);
287*0Sstevel@tonic-gate
288*0Sstevel@tonic-gate /*
289*0Sstevel@tonic-gate * Note: we don't update kstats as this entry
290*0Sstevel@tonic-gate * will eventually go away...
291*0Sstevel@tonic-gate */
292*0Sstevel@tonic-gate goto bail;
293*0Sstevel@tonic-gate
294*0Sstevel@tonic-gate }
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
297*0Sstevel@tonic-gate ibmf_sa_session_open, IBMF_TNF_TRACE, "",
298*0Sstevel@tonic-gate "ibmf_sa_session_open: %s, prefix = %016" PRIx64
299*0Sstevel@tonic-gate "\n", tnf_string, msg, "successfully initialized port");
300*0Sstevel@tonic-gate
301*0Sstevel@tonic-gate /* mark port as registered */
302*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_mutex);
303*0Sstevel@tonic-gate
304*0Sstevel@tonic-gate /* incremement reference count to account for cpi */
305*0Sstevel@tonic-gate saa_portp->saa_pt_reference_count++;
306*0Sstevel@tonic-gate
307*0Sstevel@tonic-gate saa_portp->saa_pt_state = IBMF_SAA_PORT_STATE_READY;
308*0Sstevel@tonic-gate
309*0Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*saa_portp))
310*0Sstevel@tonic-gate
311*0Sstevel@tonic-gate /* kick waiters */
312*0Sstevel@tonic-gate cv_broadcast(&saa_portp->saa_pt_ibmf_reg_cv);
313*0Sstevel@tonic-gate
314*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_mutex);
315*0Sstevel@tonic-gate
316*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
317*0Sstevel@tonic-gate ibmf_sa_session_open, IBMF_TNF_TRACE, "",
318*0Sstevel@tonic-gate "ibmf_sa_session_open: %s\n", tnf_string, msg,
319*0Sstevel@tonic-gate "port is up. Sending classportinfo request");
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate ibmf_saa_impl_get_classportinfo(saa_portp);
322*0Sstevel@tonic-gate }
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_kstat_mutex);
325*0Sstevel@tonic-gate
326*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, clients_registered, 1);
327*0Sstevel@tonic-gate
328*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_kstat_mutex);
329*0Sstevel@tonic-gate
330*0Sstevel@tonic-gate /* create new client structure */
331*0Sstevel@tonic-gate saa_client = kmem_zalloc(sizeof (saa_client_data_t), KM_SLEEP);
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*saa_client))
334*0Sstevel@tonic-gate
335*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L3,
336*0Sstevel@tonic-gate ibmf_sa_session_open, IBMF_TNF_TRACE, "",
337*0Sstevel@tonic-gate "ibmf_sa_session_open: clientp = %p, subnetp = %p\n",
338*0Sstevel@tonic-gate tnf_opaque, clientp, saa_client,
339*0Sstevel@tonic-gate tnf_opaque, subnetp, saa_portp);
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gate saa_client->saa_client_port = saa_portp;
342*0Sstevel@tonic-gate mutex_init(&saa_client->saa_client_mutex, NULL, MUTEX_DRIVER,
343*0Sstevel@tonic-gate NULL);
344*0Sstevel@tonic-gate cv_init(&saa_client->saa_client_state_cv, NULL, CV_DRIVER, NULL);
345*0Sstevel@tonic-gate cv_init(&saa_client->saa_client_event_cb_cv, NULL, CV_DRIVER, NULL);
346*0Sstevel@tonic-gate
347*0Sstevel@tonic-gate IBMF_SAA_SET_CLIENT_SIGNATURE(saa_client);
348*0Sstevel@tonic-gate
349*0Sstevel@tonic-gate saa_client->saa_client_state = SAA_CLIENT_STATE_ACTIVE;
350*0Sstevel@tonic-gate saa_client->saa_client_sm_key = sm_key;
351*0Sstevel@tonic-gate
352*0Sstevel@tonic-gate *ibmf_saa_handle = (ibmf_saa_handle_t)saa_client;
353*0Sstevel@tonic-gate
354*0Sstevel@tonic-gate /* if client is interested in subnet event notifications */
355*0Sstevel@tonic-gate if (event_args != NULL) {
356*0Sstevel@tonic-gate ibmf_saa_add_event_subscriber(saa_client, event_args);
357*0Sstevel@tonic-gate }
358*0Sstevel@tonic-gate
359*0Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*saa_client))
360*0Sstevel@tonic-gate
361*0Sstevel@tonic-gate
362*0Sstevel@tonic-gate bail:
363*0Sstevel@tonic-gate /* purge invalid entries */
364*0Sstevel@tonic-gate ibmf_saa_impl_purge();
365*0Sstevel@tonic-gate
366*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_sa_session_open_end,
367*0Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_sa_session_open() exit\n");
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gate return (status);
370*0Sstevel@tonic-gate }
371*0Sstevel@tonic-gate
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate /*
374*0Sstevel@tonic-gate * ibmf_sa_session_close()
375*0Sstevel@tonic-gate *
376*0Sstevel@tonic-gate * Unregister a consumer of the SA_Access interface
377*0Sstevel@tonic-gate *
378*0Sstevel@tonic-gate * This interface blocks.
379*0Sstevel@tonic-gate *
380*0Sstevel@tonic-gate * Arguments:
381*0Sstevel@tonic-gate * SA_Access handle
382*0Sstevel@tonic-gate *
383*0Sstevel@tonic-gate * Return values:
384*0Sstevel@tonic-gate * IBMF_SUCCESS - unregistration succeeded
385*0Sstevel@tonic-gate * IBMF_FAILURE - unregistration failed for unknown reasons
386*0Sstevel@tonic-gate *
387*0Sstevel@tonic-gate * All outstanding callbacks will be canceled before this function returns.
388*0Sstevel@tonic-gate *
389*0Sstevel@tonic-gate */
390*0Sstevel@tonic-gate /* ARGSUSED */
391*0Sstevel@tonic-gate int
ibmf_sa_session_close(ibmf_saa_handle_t * ibmf_saa_handle,uint_t flags)392*0Sstevel@tonic-gate ibmf_sa_session_close(ibmf_saa_handle_t *ibmf_saa_handle, uint_t flags)
393*0Sstevel@tonic-gate {
394*0Sstevel@tonic-gate saa_client_data_t *client_data = NULL;
395*0Sstevel@tonic-gate saa_port_t *saa_portp = NULL;
396*0Sstevel@tonic-gate int status = IBMF_SUCCESS;
397*0Sstevel@tonic-gate saa_client_data_t *curr_clientp, *prev_clientp;
398*0Sstevel@tonic-gate uint8_t port_state;
399*0Sstevel@tonic-gate
400*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
401*0Sstevel@tonic-gate ibmf_sa_session_close_start, IBMF_TNF_TRACE, "",
402*0Sstevel@tonic-gate "ibmf_sa_session_close() enter\n");
403*0Sstevel@tonic-gate
404*0Sstevel@tonic-gate if (ibmf_saa_handle == NULL) {
405*0Sstevel@tonic-gate
406*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
407*0Sstevel@tonic-gate ibmf_sa_session_close_err, IBMF_TNF_ERROR, "",
408*0Sstevel@tonic-gate "ibmf_sa_session_close: %s\n",
409*0Sstevel@tonic-gate tnf_string, msg, "invalid argument, NULL pointer argument");
410*0Sstevel@tonic-gate
411*0Sstevel@tonic-gate status = IBMF_INVALID_ARG;
412*0Sstevel@tonic-gate goto bail;
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate
415*0Sstevel@tonic-gate /* ibmf_saa_handle is pointer to the client data structure */
416*0Sstevel@tonic-gate client_data = (saa_client_data_t *)*ibmf_saa_handle;
417*0Sstevel@tonic-gate
418*0Sstevel@tonic-gate /* sanity check to make sure nothing happened to handle */
419*0Sstevel@tonic-gate if (IBMF_SAA_VERIFY_CLIENT_SIGNATURE(client_data) == B_FALSE) {
420*0Sstevel@tonic-gate
421*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
422*0Sstevel@tonic-gate ibmf_sa_session_close_err, IBMF_TNF_ERROR, "",
423*0Sstevel@tonic-gate "ibmf_sa_session_close: %s\n",
424*0Sstevel@tonic-gate tnf_string, msg, "bad handle");
425*0Sstevel@tonic-gate
426*0Sstevel@tonic-gate status = IBMF_BAD_HANDLE;
427*0Sstevel@tonic-gate goto bail;
428*0Sstevel@tonic-gate }
429*0Sstevel@tonic-gate
430*0Sstevel@tonic-gate saa_portp = client_data->saa_client_port;
431*0Sstevel@tonic-gate
432*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
433*0Sstevel@tonic-gate ibmf_sa_session_close, IBMF_TNF_TRACE,
434*0Sstevel@tonic-gate "", "ibmf_sa_session_close: saa_portp = %p\n",
435*0Sstevel@tonic-gate tnf_opaque, saa_portp, saa_portp);
436*0Sstevel@tonic-gate
437*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_mutex);
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gate port_state = saa_portp->saa_pt_state;
440*0Sstevel@tonic-gate
441*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_mutex);
442*0Sstevel@tonic-gate
443*0Sstevel@tonic-gate /*
444*0Sstevel@tonic-gate * if there are pending async transactions, wait for them to finish
445*0Sstevel@tonic-gate * note that we wait only once, not loop....
446*0Sstevel@tonic-gate * note we test the state outside saa_pt_mutex
447*0Sstevel@tonic-gate */
448*0Sstevel@tonic-gate mutex_enter(&client_data->saa_client_mutex);
449*0Sstevel@tonic-gate
450*0Sstevel@tonic-gate if ((client_data->saa_client_num_pending_trans > 0) &&
451*0Sstevel@tonic-gate (port_state == IBMF_SAA_PORT_STATE_READY)) {
452*0Sstevel@tonic-gate
453*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L3,
454*0Sstevel@tonic-gate ibmf_sa_session_close, IBMF_TNF_TRACE,
455*0Sstevel@tonic-gate "", "ibmf_sa_session_close: %s, num_pending_trans = %d\n",
456*0Sstevel@tonic-gate tnf_string, msg, "waiting for async callbacks",
457*0Sstevel@tonic-gate tnf_uint, num_pending_trans,
458*0Sstevel@tonic-gate client_data->saa_client_num_pending_trans);
459*0Sstevel@tonic-gate
460*0Sstevel@tonic-gate client_data->saa_client_state = SAA_CLIENT_STATE_WAITING;
461*0Sstevel@tonic-gate
462*0Sstevel@tonic-gate /*
463*0Sstevel@tonic-gate * we rely on IBMF calling the callback in all cases,
464*0Sstevel@tonic-gate * callback signals cv
465*0Sstevel@tonic-gate */
466*0Sstevel@tonic-gate cv_wait(&client_data->saa_client_state_cv,
467*0Sstevel@tonic-gate &client_data->saa_client_mutex);
468*0Sstevel@tonic-gate
469*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_sa_session_close,
470*0Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_sa_session_close: %s\n",
471*0Sstevel@tonic-gate tnf_string, msg, "done waiting");
472*0Sstevel@tonic-gate }
473*0Sstevel@tonic-gate
474*0Sstevel@tonic-gate /* mark state as closed so no more event callbacks will be generated */
475*0Sstevel@tonic-gate client_data->saa_client_state = SAA_CLIENT_STATE_CLOSED;
476*0Sstevel@tonic-gate
477*0Sstevel@tonic-gate /*
478*0Sstevel@tonic-gate * if there are pending subnet event callbacks wait for them to finish
479*0Sstevel@tonic-gate */
480*0Sstevel@tonic-gate if (client_data->saa_client_event_cb_num_active > 0) {
481*0Sstevel@tonic-gate
482*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L3,
483*0Sstevel@tonic-gate ibmf_sa_session_close, IBMF_TNF_TRACE,
484*0Sstevel@tonic-gate "", "ibmf_sa_session_close: %s, num_active_cb = %d\n",
485*0Sstevel@tonic-gate tnf_string, msg, "waiting for event callbacks",
486*0Sstevel@tonic-gate tnf_uint, num_active_cb,
487*0Sstevel@tonic-gate client_data->saa_client_event_cb_num_active);
488*0Sstevel@tonic-gate
489*0Sstevel@tonic-gate cv_wait(&client_data->saa_client_event_cb_cv,
490*0Sstevel@tonic-gate &client_data->saa_client_mutex);
491*0Sstevel@tonic-gate }
492*0Sstevel@tonic-gate
493*0Sstevel@tonic-gate mutex_exit(&client_data->saa_client_mutex);
494*0Sstevel@tonic-gate
495*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_kstat_mutex);
496*0Sstevel@tonic-gate
497*0Sstevel@tonic-gate IBMF_SAA_SUB32_KSTATS(saa_portp, clients_registered, 1);
498*0Sstevel@tonic-gate
499*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_kstat_mutex);
500*0Sstevel@tonic-gate
501*0Sstevel@tonic-gate /*
502*0Sstevel@tonic-gate * if client was subscribed for events then remove the callback from the
503*0Sstevel@tonic-gate * list, and possibly unsubscribe from the SA
504*0Sstevel@tonic-gate */
505*0Sstevel@tonic-gate if (client_data->saa_client_event_cb != NULL) {
506*0Sstevel@tonic-gate
507*0Sstevel@tonic-gate /* remove the client from the port's list of clients */
508*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_event_sub_mutex);
509*0Sstevel@tonic-gate
510*0Sstevel@tonic-gate curr_clientp = saa_portp->saa_pt_event_sub_client_list;
511*0Sstevel@tonic-gate prev_clientp = NULL;
512*0Sstevel@tonic-gate while (curr_clientp != NULL) {
513*0Sstevel@tonic-gate
514*0Sstevel@tonic-gate if (curr_clientp == client_data) {
515*0Sstevel@tonic-gate
516*0Sstevel@tonic-gate break;
517*0Sstevel@tonic-gate }
518*0Sstevel@tonic-gate
519*0Sstevel@tonic-gate prev_clientp = curr_clientp;
520*0Sstevel@tonic-gate curr_clientp = curr_clientp->next;
521*0Sstevel@tonic-gate }
522*0Sstevel@tonic-gate
523*0Sstevel@tonic-gate /* should have found the client */
524*0Sstevel@tonic-gate ASSERT(curr_clientp != NULL);
525*0Sstevel@tonic-gate
526*0Sstevel@tonic-gate if (curr_clientp == NULL) {
527*0Sstevel@tonic-gate
528*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
529*0Sstevel@tonic-gate ibmf_sa_session_close, IBMF_TNF_ERROR, "",
530*0Sstevel@tonic-gate "ibmf_sa_session_close: %s. ref_count = %d\n",
531*0Sstevel@tonic-gate tnf_string, msg, "could not find client in list",
532*0Sstevel@tonic-gate tnf_opaque, client, client_data);
533*0Sstevel@tonic-gate } else {
534*0Sstevel@tonic-gate
535*0Sstevel@tonic-gate if (prev_clientp == NULL) {
536*0Sstevel@tonic-gate
537*0Sstevel@tonic-gate saa_portp->saa_pt_event_sub_client_list =
538*0Sstevel@tonic-gate curr_clientp->next;
539*0Sstevel@tonic-gate
540*0Sstevel@tonic-gate } else
541*0Sstevel@tonic-gate prev_clientp->next = curr_clientp->next;
542*0Sstevel@tonic-gate
543*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
544*0Sstevel@tonic-gate ibmf_sa_session_close, IBMF_TNF_TRACE, "",
545*0Sstevel@tonic-gate "ibmf_sa_session_close: %s\n", tnf_string, msg,
546*0Sstevel@tonic-gate "Removed client from event subscriber list");
547*0Sstevel@tonic-gate }
548*0Sstevel@tonic-gate
549*0Sstevel@tonic-gate
550*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_event_sub_mutex);
551*0Sstevel@tonic-gate
552*0Sstevel@tonic-gate }
553*0Sstevel@tonic-gate
554*0Sstevel@tonic-gate /* decrementing refcount is last thing we do on port entry */
555*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_mutex);
556*0Sstevel@tonic-gate
557*0Sstevel@tonic-gate ASSERT(saa_portp->saa_pt_reference_count > 0);
558*0Sstevel@tonic-gate saa_portp->saa_pt_reference_count--;
559*0Sstevel@tonic-gate
560*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_sa_session_close,
561*0Sstevel@tonic-gate IBMF_TNF_TRACE, "",
562*0Sstevel@tonic-gate "ibmf_sa_session_close: ref_count = %d\n",
563*0Sstevel@tonic-gate tnf_uint, port_ref_count,
564*0Sstevel@tonic-gate saa_portp->saa_pt_reference_count);
565*0Sstevel@tonic-gate
566*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_mutex);
567*0Sstevel@tonic-gate
568*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L3,
569*0Sstevel@tonic-gate ibmf_sa_session_close, IBMF_TNF_TRACE, "",
570*0Sstevel@tonic-gate "ibmf_sa_session_close: %s, clientp = %p\n", tnf_string, msg,
571*0Sstevel@tonic-gate "freeing client memory", tnf_opaque, clientp, *ibmf_saa_handle);
572*0Sstevel@tonic-gate
573*0Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*client_data))
574*0Sstevel@tonic-gate
575*0Sstevel@tonic-gate /* destroy client */
576*0Sstevel@tonic-gate mutex_destroy(&client_data->saa_client_mutex);
577*0Sstevel@tonic-gate
578*0Sstevel@tonic-gate cv_destroy(&client_data->saa_client_state_cv);
579*0Sstevel@tonic-gate cv_destroy(&client_data->saa_client_event_cb_cv);
580*0Sstevel@tonic-gate
581*0Sstevel@tonic-gate IBMF_SAA_CLEAR_CLIENT_SIGNATURE(client_data);
582*0Sstevel@tonic-gate
583*0Sstevel@tonic-gate kmem_free(*ibmf_saa_handle, sizeof (saa_client_data_t));
584*0Sstevel@tonic-gate
585*0Sstevel@tonic-gate *ibmf_saa_handle = NULL;
586*0Sstevel@tonic-gate
587*0Sstevel@tonic-gate bail:
588*0Sstevel@tonic-gate /* purge invalid entries */
589*0Sstevel@tonic-gate ibmf_saa_impl_purge();
590*0Sstevel@tonic-gate
591*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_sa_session_close_end,
592*0Sstevel@tonic-gate IBMF_TNF_TRACE, "", "ibmf_sa_session_close() exit\n");
593*0Sstevel@tonic-gate
594*0Sstevel@tonic-gate return (status);
595*0Sstevel@tonic-gate }
596*0Sstevel@tonic-gate
597*0Sstevel@tonic-gate /*
598*0Sstevel@tonic-gate * ibmf_sa_access
599*0Sstevel@tonic-gate *
600*0Sstevel@tonic-gate * Retrieve records from the SA given an AttributeID, ComponentMask,
601*0Sstevel@tonic-gate * and a template
602*0Sstevel@tonic-gate *
603*0Sstevel@tonic-gate * This interface blocks if the callback parameter is NULL.
604*0Sstevel@tonic-gate *
605*0Sstevel@tonic-gate * Input Arguments:
606*0Sstevel@tonic-gate * ibmf_saa_handle - handle returned from ibmf_sa_session_open()
607*0Sstevel@tonic-gate * access_args - structure containing various parameters for the query
608*0Sstevel@tonic-gate * flags - unsused
609*0Sstevel@tonic-gate *
610*0Sstevel@tonic-gate * Output Arguments:
611*0Sstevel@tonic-gate * length - size of buffer returned
612*0Sstevel@tonic-gate * result - pointer to buffer of records returned in response.
613*0Sstevel@tonic-gate * Buffer is host-endian, unpacked and can be cast to one
614*0Sstevel@tonic-gate * of the record types in sa_recs.h
615*0Sstevel@tonic-gate * Return values:
616*0Sstevel@tonic-gate * IBMF_SUCCESS - query succeeded
617*0Sstevel@tonic-gate * IBMF_BAD_HANDLE - sa session handle is invalid
618*0Sstevel@tonic-gate * IBMF_BAD_PORT_STATE - port in incorrect state
619*0Sstevel@tonic-gate * IBMF_INVALID_ARG - one of the pointer parameters was NULL
620*0Sstevel@tonic-gate * IBMF_NO_RESOURCES - ibmf could not allocate ib resources or SA returned
621*0Sstevel@tonic-gate * ERR_NO_RESOURCES
622*0Sstevel@tonic-gate * IBMF_TRANS_TIMEOUT - transaction timed out
623*0Sstevel@tonic-gate * IBMF_TRANS_FAILURE - transaction failure
624*0Sstevel@tonic-gate * IBMF_NO_MEMORY - ibmf could not allocate memory
625*0Sstevel@tonic-gate * IBMF_REQ_INVALID - send and recv buffer the same for a sequenced
626*0Sstevel@tonic-gate * transaction or the SA returned an ERR_REQ_INVALID
627*0Sstevel@tonic-gate * IBMF_NO_RECORDS - no records matched query
628*0Sstevel@tonic-gate * IBMF_TOO_MANY_RECORDS- SA returned SA_ERR_TOO_MANY_RECORDS
629*0Sstevel@tonic-gate * IBMF_INVALID_GID - SA returned SA_INVALID_GID
630*0Sstevel@tonic-gate * IBMF_INSUFF_COMPS - SA returned SA_ERR_INSUFFICIENT_COMPS
631*0Sstevel@tonic-gate * IBMF_UNSUPP_METHOD - SA returned MAD_STATUS_UNSUPP_METHOD
632*0Sstevel@tonic-gate * IBMF_UNSUPP_METHOD_ATTR - SA returned MAD_STATUS_UNSUPP_METHOD_ATTR
633*0Sstevel@tonic-gate * IBMF_INVALID_FIELD - SA returned MAD_STATUS_INVALID_FIELD
634*0Sstevel@tonic-gate *
635*0Sstevel@tonic-gate * Upon successful completion, result points to a buffer containing the records.
636*0Sstevel@tonic-gate * length is the size in bytes of the buffer returned in result. If there are
637*0Sstevel@tonic-gate * no records or the call failed the length is 0.
638*0Sstevel@tonic-gate *
639*0Sstevel@tonic-gate * The consumer is responsible for freeing the memory associated with result.
640*0Sstevel@tonic-gate */
641*0Sstevel@tonic-gate /* ARGSUSED */
642*0Sstevel@tonic-gate int
ibmf_sa_access(ibmf_saa_handle_t ibmf_saa_handle,ibmf_saa_access_args_t * access_args,uint_t flags,size_t * length,void ** result)643*0Sstevel@tonic-gate ibmf_sa_access(ibmf_saa_handle_t ibmf_saa_handle,
644*0Sstevel@tonic-gate ibmf_saa_access_args_t *access_args, uint_t flags, size_t *length,
645*0Sstevel@tonic-gate void **result)
646*0Sstevel@tonic-gate {
647*0Sstevel@tonic-gate int res = IBMF_SUCCESS;
648*0Sstevel@tonic-gate
649*0Sstevel@tonic-gate saa_impl_trans_info_t *trans_info;
650*0Sstevel@tonic-gate saa_client_data_t *clientp;
651*0Sstevel@tonic-gate saa_port_t *saa_portp;
652*0Sstevel@tonic-gate
653*0Sstevel@tonic-gate IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L3,
654*0Sstevel@tonic-gate ibmf_sa_access_start, IBMF_TNF_TRACE, "",
655*0Sstevel@tonic-gate "ibmf_sa_access_start() enter. attr_id = 0x%x, access_type ="
656*0Sstevel@tonic-gate " 0x%x, comp_mask = %016" PRIx64 "\n",
657*0Sstevel@tonic-gate tnf_opaque, attr_id, access_args->sq_attr_id,
658*0Sstevel@tonic-gate tnf_opaque, access_type, access_args->sq_access_type,
659*0Sstevel@tonic-gate tnf_opaque, comp_mask, access_args->sq_component_mask);
660*0Sstevel@tonic-gate
661*0Sstevel@tonic-gate if ((access_args == NULL) || (length == NULL) || (result == NULL)) {
662*0Sstevel@tonic-gate
663*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
664*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
665*0Sstevel@tonic-gate "ibmf_sa_access: %s\n",
666*0Sstevel@tonic-gate tnf_string, msg, "invalid argument, NULL pointer argument");
667*0Sstevel@tonic-gate
668*0Sstevel@tonic-gate res = IBMF_INVALID_ARG;
669*0Sstevel@tonic-gate goto bail;
670*0Sstevel@tonic-gate }
671*0Sstevel@tonic-gate
672*0Sstevel@tonic-gate /* sanity check to make sure nothing happened to handle */
673*0Sstevel@tonic-gate if (IBMF_SAA_VERIFY_CLIENT_SIGNATURE(
674*0Sstevel@tonic-gate (saa_client_data_t *)ibmf_saa_handle) == B_FALSE) {
675*0Sstevel@tonic-gate
676*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
677*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
678*0Sstevel@tonic-gate "ibmf_sa_access: %s\n",
679*0Sstevel@tonic-gate tnf_string, msg, "bad handle");
680*0Sstevel@tonic-gate
681*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
682*0Sstevel@tonic-gate ibmf_sa_access_end, IBMF_TNF_TRACE,
683*0Sstevel@tonic-gate "", "ibmf_sa_access() exit\n");
684*0Sstevel@tonic-gate
685*0Sstevel@tonic-gate res = IBMF_BAD_HANDLE;
686*0Sstevel@tonic-gate goto bail;
687*0Sstevel@tonic-gate }
688*0Sstevel@tonic-gate
689*0Sstevel@tonic-gate if (access_args->sq_callback == NULL) {
690*0Sstevel@tonic-gate
691*0Sstevel@tonic-gate trans_info = kmem_zalloc(sizeof (saa_impl_trans_info_t),
692*0Sstevel@tonic-gate KM_SLEEP);
693*0Sstevel@tonic-gate } else {
694*0Sstevel@tonic-gate trans_info = kmem_zalloc(sizeof (saa_impl_trans_info_t),
695*0Sstevel@tonic-gate KM_NOSLEEP);
696*0Sstevel@tonic-gate if (trans_info == NULL) {
697*0Sstevel@tonic-gate
698*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
699*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
700*0Sstevel@tonic-gate "ibmf_sa_access: %s\n", tnf_string, msg,
701*0Sstevel@tonic-gate "could not allocate memory for trans_info");
702*0Sstevel@tonic-gate
703*0Sstevel@tonic-gate res = IBMF_NO_MEMORY;
704*0Sstevel@tonic-gate goto bail;
705*0Sstevel@tonic-gate }
706*0Sstevel@tonic-gate }
707*0Sstevel@tonic-gate
708*0Sstevel@tonic-gate clientp = (saa_client_data_t *)ibmf_saa_handle;
709*0Sstevel@tonic-gate saa_portp = clientp->saa_client_port;
710*0Sstevel@tonic-gate
711*0Sstevel@tonic-gate trans_info->si_trans_client_data = clientp;
712*0Sstevel@tonic-gate trans_info->si_trans_port = saa_portp;
713*0Sstevel@tonic-gate
714*0Sstevel@tonic-gate /*
715*0Sstevel@tonic-gate * method is get_multi if attribute is multipath; otherwise method is
716*0Sstevel@tonic-gate * based on query type
717*0Sstevel@tonic-gate */
718*0Sstevel@tonic-gate if (access_args->sq_attr_id == SA_MULTIPATHRECORD_ATTRID) {
719*0Sstevel@tonic-gate
720*0Sstevel@tonic-gate if (access_args->sq_access_type != IBMF_SAA_RETRIEVE) {
721*0Sstevel@tonic-gate
722*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
723*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
724*0Sstevel@tonic-gate "ibmf_sa_access: %s, access_type = 0x%x\n",
725*0Sstevel@tonic-gate tnf_string, msg, "access_type for multi-path"
726*0Sstevel@tonic-gate " records must be IBMF_SAA_RETRIEVE",
727*0Sstevel@tonic-gate tnf_opaque, access_type,
728*0Sstevel@tonic-gate access_args->sq_access_type);
729*0Sstevel@tonic-gate
730*0Sstevel@tonic-gate kmem_free(trans_info, sizeof (saa_impl_trans_info_t));
731*0Sstevel@tonic-gate
732*0Sstevel@tonic-gate res = IBMF_REQ_INVALID;
733*0Sstevel@tonic-gate goto bail;
734*0Sstevel@tonic-gate }
735*0Sstevel@tonic-gate
736*0Sstevel@tonic-gate trans_info->si_trans_method = SA_SUBN_ADM_GET_MULTI;
737*0Sstevel@tonic-gate } else if (access_args->sq_attr_id == SA_TRACERECORD_ATTRID) {
738*0Sstevel@tonic-gate
739*0Sstevel@tonic-gate if (access_args->sq_access_type != IBMF_SAA_RETRIEVE) {
740*0Sstevel@tonic-gate
741*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
742*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
743*0Sstevel@tonic-gate "ibmf_sa_access: %s, access_type = 0x%x\n",
744*0Sstevel@tonic-gate tnf_string, msg, "access_type for trace"
745*0Sstevel@tonic-gate " records must be IBMF_SAA_RETRIEVE",
746*0Sstevel@tonic-gate tnf_opaque, access_type,
747*0Sstevel@tonic-gate access_args->sq_access_type);
748*0Sstevel@tonic-gate
749*0Sstevel@tonic-gate kmem_free(trans_info, sizeof (saa_impl_trans_info_t));
750*0Sstevel@tonic-gate
751*0Sstevel@tonic-gate res = IBMF_REQ_INVALID;
752*0Sstevel@tonic-gate goto bail;
753*0Sstevel@tonic-gate }
754*0Sstevel@tonic-gate
755*0Sstevel@tonic-gate trans_info->si_trans_method = SA_SUBN_ADM_GET_TRACE_TABLE;
756*0Sstevel@tonic-gate } else {
757*0Sstevel@tonic-gate
758*0Sstevel@tonic-gate switch (access_args->sq_access_type) {
759*0Sstevel@tonic-gate
760*0Sstevel@tonic-gate case IBMF_SAA_RETRIEVE:
761*0Sstevel@tonic-gate trans_info->si_trans_method =
762*0Sstevel@tonic-gate SA_SUBN_ADM_GET_TABLE;
763*0Sstevel@tonic-gate break;
764*0Sstevel@tonic-gate case IBMF_SAA_UPDATE:
765*0Sstevel@tonic-gate trans_info->si_trans_method = SA_SUBN_ADM_SET;
766*0Sstevel@tonic-gate break;
767*0Sstevel@tonic-gate case IBMF_SAA_DELETE:
768*0Sstevel@tonic-gate trans_info->si_trans_method =
769*0Sstevel@tonic-gate SA_SUBN_ADM_DELETE;
770*0Sstevel@tonic-gate break;
771*0Sstevel@tonic-gate default:
772*0Sstevel@tonic-gate
773*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
774*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
775*0Sstevel@tonic-gate "ibmf_sa_access: %s, access_type = 0x%x\n",
776*0Sstevel@tonic-gate tnf_string, msg, "unknown access_type",
777*0Sstevel@tonic-gate tnf_opaque, access_type,
778*0Sstevel@tonic-gate access_args->sq_access_type);
779*0Sstevel@tonic-gate
780*0Sstevel@tonic-gate kmem_free(trans_info,
781*0Sstevel@tonic-gate sizeof (saa_impl_trans_info_t));
782*0Sstevel@tonic-gate
783*0Sstevel@tonic-gate res = IBMF_REQ_INVALID;
784*0Sstevel@tonic-gate goto bail;
785*0Sstevel@tonic-gate }
786*0Sstevel@tonic-gate }
787*0Sstevel@tonic-gate
788*0Sstevel@tonic-gate trans_info->si_trans_attr_id = access_args->sq_attr_id;
789*0Sstevel@tonic-gate trans_info->si_trans_component_mask = access_args->sq_component_mask;
790*0Sstevel@tonic-gate trans_info->si_trans_template = access_args->sq_template;
791*0Sstevel@tonic-gate trans_info->si_trans_template_length = access_args->sq_template_length;
792*0Sstevel@tonic-gate trans_info->si_trans_callback = access_args->sq_callback;
793*0Sstevel@tonic-gate trans_info->si_trans_callback_arg = access_args->sq_callback_arg;
794*0Sstevel@tonic-gate
795*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_kstat_mutex);
796*0Sstevel@tonic-gate
797*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, outstanding_requests, 1);
798*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, total_requests, 1);
799*0Sstevel@tonic-gate
800*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_kstat_mutex);
801*0Sstevel@tonic-gate
802*0Sstevel@tonic-gate res = ibmf_saa_impl_send_request(trans_info);
803*0Sstevel@tonic-gate if (res != IBMF_SUCCESS) {
804*0Sstevel@tonic-gate
805*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
806*0Sstevel@tonic-gate ibmf_sa_access_err, IBMF_TNF_ERROR, "",
807*0Sstevel@tonic-gate "ibmf_sa_access: %s, ibmf_status = %d\n",
808*0Sstevel@tonic-gate tnf_string, msg, "ibmf_saa_impl_send_request() failed",
809*0Sstevel@tonic-gate tnf_int, ibmf_status, res);
810*0Sstevel@tonic-gate
811*0Sstevel@tonic-gate *length = 0;
812*0Sstevel@tonic-gate *result = NULL;
813*0Sstevel@tonic-gate
814*0Sstevel@tonic-gate kmem_free(trans_info, sizeof (saa_impl_trans_info_t));
815*0Sstevel@tonic-gate
816*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_kstat_mutex);
817*0Sstevel@tonic-gate
818*0Sstevel@tonic-gate IBMF_SAA_SUB32_KSTATS(saa_portp, outstanding_requests, 1);
819*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, failed_requests, 1);
820*0Sstevel@tonic-gate
821*0Sstevel@tonic-gate if (res == IBMF_TRANS_TIMEOUT)
822*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, requests_timedout,
823*0Sstevel@tonic-gate 1);
824*0Sstevel@tonic-gate
825*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_kstat_mutex);
826*0Sstevel@tonic-gate
827*0Sstevel@tonic-gate goto bail;
828*0Sstevel@tonic-gate }
829*0Sstevel@tonic-gate
830*0Sstevel@tonic-gate /*
831*0Sstevel@tonic-gate * if async call don't do anything as callback will take care of
832*0Sstevel@tonic-gate * everything; for sync call, copy parameters back to client and free
833*0Sstevel@tonic-gate * trans_info structure
834*0Sstevel@tonic-gate */
835*0Sstevel@tonic-gate if (access_args->sq_callback == NULL) {
836*0Sstevel@tonic-gate *length = trans_info->si_trans_length;
837*0Sstevel@tonic-gate *result = trans_info->si_trans_result;
838*0Sstevel@tonic-gate res = trans_info->si_trans_status;
839*0Sstevel@tonic-gate
840*0Sstevel@tonic-gate mutex_enter(&saa_portp->saa_pt_kstat_mutex);
841*0Sstevel@tonic-gate
842*0Sstevel@tonic-gate IBMF_SAA_SUB32_KSTATS(saa_portp, outstanding_requests, 1);
843*0Sstevel@tonic-gate
844*0Sstevel@tonic-gate if (res != IBMF_SUCCESS)
845*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, failed_requests,
846*0Sstevel@tonic-gate 1);
847*0Sstevel@tonic-gate
848*0Sstevel@tonic-gate if (res == IBMF_TRANS_TIMEOUT)
849*0Sstevel@tonic-gate IBMF_SAA_ADD32_KSTATS(saa_portp, requests_timedout,
850*0Sstevel@tonic-gate 1);
851*0Sstevel@tonic-gate
852*0Sstevel@tonic-gate mutex_exit(&saa_portp->saa_pt_kstat_mutex);
853*0Sstevel@tonic-gate
854*0Sstevel@tonic-gate kmem_free(trans_info, sizeof (saa_impl_trans_info_t));
855*0Sstevel@tonic-gate }
856*0Sstevel@tonic-gate
857*0Sstevel@tonic-gate bail:
858*0Sstevel@tonic-gate
859*0Sstevel@tonic-gate if (res != IBMF_SUCCESS) {
860*0Sstevel@tonic-gate if (length != NULL)
861*0Sstevel@tonic-gate *length = 0;
862*0Sstevel@tonic-gate if (result != NULL)
863*0Sstevel@tonic-gate *result = NULL;
864*0Sstevel@tonic-gate }
865*0Sstevel@tonic-gate
866*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_sa_access, IBMF_TNF_TRACE,
867*0Sstevel@tonic-gate "", "ibmf_sa_access() exit: result = 0x%x\n",
868*0Sstevel@tonic-gate tnf_opaque, result, res);
869*0Sstevel@tonic-gate
870*0Sstevel@tonic-gate return (res);
871*0Sstevel@tonic-gate }
872*0Sstevel@tonic-gate
873*0Sstevel@tonic-gate /*
874*0Sstevel@tonic-gate * Helper Functions.
875*0Sstevel@tonic-gate * Ease of use functions so that the consumer doesn't
876*0Sstevel@tonic-gate * have to do the overhead of calling ibmf_sa_access for
877*0Sstevel@tonic-gate * commonly used queries
878*0Sstevel@tonic-gate */
879*0Sstevel@tonic-gate
880*0Sstevel@tonic-gate /*
881*0Sstevel@tonic-gate * ibmf_saa_gid_to_pathrecords
882*0Sstevel@tonic-gate * Given a source gid and a destination gid, return paths
883*0Sstevel@tonic-gate * between the gids.
884*0Sstevel@tonic-gate *
885*0Sstevel@tonic-gate * This interface blocks.
886*0Sstevel@tonic-gate *
887*0Sstevel@tonic-gate * Input Arguments:
888*0Sstevel@tonic-gate * ibmf_saa_handle - handle returned from ibmf_sa_session_open()
889*0Sstevel@tonic-gate * sgid - source gid of path
890*0Sstevel@tonic-gate * dgid - destination gid of path
891*0Sstevel@tonic-gate * p_key - partition of path. This value may be wildcarded with
892*0Sstevel@tonic-gate * IBMF_SAA_PKEY_WC.
893*0Sstevel@tonic-gate * mtu - preferred MTU of the path. This argument may be
894*0Sstevel@tonic-gate * wildcarded with IBMF_SAA_MTU_WC.
895*0Sstevel@tonic-gate * reversible - if B_TRUE, ibmf will query only reversible paths
896*0Sstevel@tonic-gate * see Infiniband Specification table 171
897*0Sstevel@tonic-gate * num_paths - maximum number of paths to return
898*0Sstevel@tonic-gate * num_paths should be checked for the actual number of
899*0Sstevel@tonic-gate * records returned.
900*0Sstevel@tonic-gate * flags - unused
901*0Sstevel@tonic-gate *
902*0Sstevel@tonic-gate * Output Arguments:
903*0Sstevel@tonic-gate * num_paths - actual number of paths returned
904*0Sstevel@tonic-gate * length - size of buffer returned
905*0Sstevel@tonic-gate * result - pointer to buffer of path records returned in response
906*0Sstevel@tonic-gate *
907*0Sstevel@tonic-gate * Return values:
908*0Sstevel@tonic-gate * Error codes are the same as ibmf_sa_access() return values
909*0Sstevel@tonic-gate *
910*0Sstevel@tonic-gate * Upon successful completion, result points to a buffer containing the records.
911*0Sstevel@tonic-gate * length is the size in bytes of the buffer returned in result. If there are
912*0Sstevel@tonic-gate * no records or the call failed the length is 0.
913*0Sstevel@tonic-gate *
914*0Sstevel@tonic-gate * The consumer is responsible for freeing the memory associated with result.
915*0Sstevel@tonic-gate */
916*0Sstevel@tonic-gate /* ARGSUSED */
917*0Sstevel@tonic-gate int
ibmf_saa_gid_to_pathrecords(ibmf_saa_handle_t ibmf_saa_handle,ib_gid_t sgid,ib_gid_t dgid,ib_pkey_t p_key,ib_mtu_t mtu,boolean_t reversible,uint8_t * num_paths,uint_t flags,size_t * length,sa_path_record_t ** result)918*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords(ibmf_saa_handle_t ibmf_saa_handle, ib_gid_t sgid,
919*0Sstevel@tonic-gate ib_gid_t dgid, ib_pkey_t p_key, ib_mtu_t mtu, boolean_t reversible,
920*0Sstevel@tonic-gate uint8_t *num_paths, uint_t flags, size_t *length, sa_path_record_t **result)
921*0Sstevel@tonic-gate {
922*0Sstevel@tonic-gate sa_path_record_t path_record;
923*0Sstevel@tonic-gate uint64_t comp_mask;
924*0Sstevel@tonic-gate int res;
925*0Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
926*0Sstevel@tonic-gate
927*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
928*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords_start, IBMF_TNF_TRACE, "",
929*0Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords() enter\n");
930*0Sstevel@tonic-gate
931*0Sstevel@tonic-gate /*
932*0Sstevel@tonic-gate * check num_paths pointer here since we dereference before calling
933*0Sstevel@tonic-gate * ibmf_sa_access
934*0Sstevel@tonic-gate */
935*0Sstevel@tonic-gate if (num_paths == NULL) {
936*0Sstevel@tonic-gate
937*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_NODEBUG, DPRINT_L1,
938*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords_err, IBMF_TNF_ERROR, "",
939*0Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords: %s\n",
940*0Sstevel@tonic-gate tnf_string, msg, "invalid argument, NULL pointer argument");
941*0Sstevel@tonic-gate
942*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
943*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords_end, IBMF_TNF_TRACE,
944*0Sstevel@tonic-gate "", "ibmf_saa_gid_to_pathrecords() exit\n");
945*0Sstevel@tonic-gate
946*0Sstevel@tonic-gate if (length != NULL)
947*0Sstevel@tonic-gate *length = 0;
948*0Sstevel@tonic-gate if (result != NULL)
949*0Sstevel@tonic-gate *result = NULL;
950*0Sstevel@tonic-gate
951*0Sstevel@tonic-gate return (IBMF_INVALID_ARG);
952*0Sstevel@tonic-gate }
953*0Sstevel@tonic-gate
954*0Sstevel@tonic-gate /* check valid handle; in non-debug system ibmf_sa_access() will fail */
955*0Sstevel@tonic-gate ASSERT(ibmf_saa_handle != NULL);
956*0Sstevel@tonic-gate
957*0Sstevel@tonic-gate ASSERT(length != NULL);
958*0Sstevel@tonic-gate ASSERT(result != NULL);
959*0Sstevel@tonic-gate
960*0Sstevel@tonic-gate *length = 0;
961*0Sstevel@tonic-gate *result = NULL;
962*0Sstevel@tonic-gate
963*0Sstevel@tonic-gate comp_mask = SA_PR_COMPMASK_SGID | SA_PR_COMPMASK_DGID |
964*0Sstevel@tonic-gate SA_PR_COMPMASK_NUMBPATH;
965*0Sstevel@tonic-gate
966*0Sstevel@tonic-gate bzero(&path_record, sizeof (sa_path_record_t));
967*0Sstevel@tonic-gate
968*0Sstevel@tonic-gate path_record.SGID = sgid;
969*0Sstevel@tonic-gate path_record.DGID = dgid;
970*0Sstevel@tonic-gate path_record.NumbPath = *num_paths;
971*0Sstevel@tonic-gate
972*0Sstevel@tonic-gate if (reversible == B_TRUE) {
973*0Sstevel@tonic-gate path_record.Reversible = 1;
974*0Sstevel@tonic-gate comp_mask |= SA_PR_COMPMASK_REVERSIBLE;
975*0Sstevel@tonic-gate }
976*0Sstevel@tonic-gate
977*0Sstevel@tonic-gate if (p_key != IBMF_SAA_PKEY_WC) {
978*0Sstevel@tonic-gate
979*0Sstevel@tonic-gate path_record.P_Key = p_key;
980*0Sstevel@tonic-gate comp_mask |= SA_PR_COMPMASK_PKEY;
981*0Sstevel@tonic-gate }
982*0Sstevel@tonic-gate
983*0Sstevel@tonic-gate /*
984*0Sstevel@tonic-gate * gid_to_pathrecords specifies greater than or equal to MTU. Path
985*0Sstevel@tonic-gate * records can only do strictly greater. Set the mtu value to one
986*0Sstevel@tonic-gate * less than the mtu parameter. If it's the lowest value possible (256)
987*0Sstevel@tonic-gate * don't do anything and any path mtu will be allowed.
988*0Sstevel@tonic-gate */
989*0Sstevel@tonic-gate if ((mtu != IBMF_SAA_MTU_WC) && (mtu > IB_MTU_256)) {
990*0Sstevel@tonic-gate
991*0Sstevel@tonic-gate path_record.MtuSelector = SA_PR_MTU_SEL_GREATER;
992*0Sstevel@tonic-gate path_record.Mtu = (mtu - 1);
993*0Sstevel@tonic-gate
994*0Sstevel@tonic-gate comp_mask |= SA_PR_COMPMASK_MTUSELECTOR | SA_PR_COMPMASK_MTU;
995*0Sstevel@tonic-gate }
996*0Sstevel@tonic-gate
997*0Sstevel@tonic-gate access_args.sq_attr_id = SA_PATHRECORD_ATTRID;
998*0Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
999*0Sstevel@tonic-gate access_args.sq_component_mask = comp_mask;
1000*0Sstevel@tonic-gate access_args.sq_template = &path_record;
1001*0Sstevel@tonic-gate access_args.sq_callback = NULL;
1002*0Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
1003*0Sstevel@tonic-gate
1004*0Sstevel@tonic-gate res = ibmf_sa_access(ibmf_saa_handle, &access_args, 0, length,
1005*0Sstevel@tonic-gate (void **)result);
1006*0Sstevel@tonic-gate if (res != IBMF_SUCCESS) {
1007*0Sstevel@tonic-gate
1008*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L2,
1009*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords, IBMF_TNF_TRACE, "",
1010*0Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords: %s, ibmf_status = %d\n",
1011*0Sstevel@tonic-gate tnf_string, msg, "ibmf_sa_access() failed",
1012*0Sstevel@tonic-gate tnf_int, ibmf_status, res);
1013*0Sstevel@tonic-gate }
1014*0Sstevel@tonic-gate
1015*0Sstevel@tonic-gate *num_paths = *length / sizeof (sa_path_record_t);
1016*0Sstevel@tonic-gate
1017*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
1018*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords_end, IBMF_TNF_TRACE, "",
1019*0Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords() exit: result = 0x%x\n",
1020*0Sstevel@tonic-gate tnf_opaque, result, res);
1021*0Sstevel@tonic-gate
1022*0Sstevel@tonic-gate return (res);
1023*0Sstevel@tonic-gate }
1024*0Sstevel@tonic-gate
1025*0Sstevel@tonic-gate /*
1026*0Sstevel@tonic-gate * ibmf_saa_paths_from_gid
1027*0Sstevel@tonic-gate * Given a source GID, return a path from the source gid
1028*0Sstevel@tonic-gate * to every other port on the subnet. It is assumed that the
1029*0Sstevel@tonic-gate * subnet is fully connected. Only one path per port on the subnet
1030*0Sstevel@tonic-gate * is returned.
1031*0Sstevel@tonic-gate *
1032*0Sstevel@tonic-gate * This interface blocks.
1033*0Sstevel@tonic-gate *
1034*0Sstevel@tonic-gate * Input Arguments:
1035*0Sstevel@tonic-gate * ibmf_saa_handle - handle returned from ibmf_sa_session_open()
1036*0Sstevel@tonic-gate * sgid - source gid of path
1037*0Sstevel@tonic-gate * pkey - paritition of path. This value may be wildcarded with
1038*0Sstevel@tonic-gate * IBMF_SAA_PKEY_WC.
1039*0Sstevel@tonic-gate * reversible - if B_TRUE, ibmf will query only reversible paths;
1040*0Sstevel@tonic-gate * see Infiniband Specification table 171
1041*0Sstevel@tonic-gate * flags - unused
1042*0Sstevel@tonic-gate *
1043*0Sstevel@tonic-gate * Output Arguments:
1044*0Sstevel@tonic-gate * num_paths - number of paths returned
1045*0Sstevel@tonic-gate * length - size of buffer returned
1046*0Sstevel@tonic-gate * result - pointer to buffer of path records returned in response
1047*0Sstevel@tonic-gate *
1048*0Sstevel@tonic-gate * Return values:
1049*0Sstevel@tonic-gate * Error codes are the same as ibmf_sa_access() return values
1050*0Sstevel@tonic-gate *
1051*0Sstevel@tonic-gate * Upon successful completion, result points to a buffer containing the records.
1052*0Sstevel@tonic-gate * and num_records is the number of path records returned. length is the size
1053*0Sstevel@tonic-gate * in bytes of the buffer returned in result. If there are no records or the
1054*0Sstevel@tonic-gate * call failed the length is 0.
1055*0Sstevel@tonic-gate *
1056*0Sstevel@tonic-gate * The consumer is responsible for freeing the memory associated with result.
1057*0Sstevel@tonic-gate */
1058*0Sstevel@tonic-gate /* ARGSUSED */
1059*0Sstevel@tonic-gate int
ibmf_saa_paths_from_gid(ibmf_saa_handle_t ibmf_saa_handle,ib_gid_t sgid,ib_pkey_t p_key,boolean_t reversible,uint_t flags,uint_t * num_paths,size_t * length,sa_path_record_t ** result)1060*0Sstevel@tonic-gate ibmf_saa_paths_from_gid(ibmf_saa_handle_t ibmf_saa_handle, ib_gid_t sgid,
1061*0Sstevel@tonic-gate ib_pkey_t p_key, boolean_t reversible, uint_t flags, uint_t *num_paths,
1062*0Sstevel@tonic-gate size_t *length, sa_path_record_t **result)
1063*0Sstevel@tonic-gate {
1064*0Sstevel@tonic-gate sa_path_record_t path_record;
1065*0Sstevel@tonic-gate uint64_t comp_mask;
1066*0Sstevel@tonic-gate int res;
1067*0Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
1068*0Sstevel@tonic-gate
1069*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1070*0Sstevel@tonic-gate ibmf_saa_paths_from_gid_start, IBMF_TNF_TRACE, "",
1071*0Sstevel@tonic-gate "ibmf_saa_paths_from_gid() enter\n");
1072*0Sstevel@tonic-gate
1073*0Sstevel@tonic-gate /* check valid handle; in non-debug system ibmf_sa_access() will fail */
1074*0Sstevel@tonic-gate ASSERT(ibmf_saa_handle != NULL);
1075*0Sstevel@tonic-gate
1076*0Sstevel@tonic-gate ASSERT(length != NULL);
1077*0Sstevel@tonic-gate ASSERT(result != NULL);
1078*0Sstevel@tonic-gate
1079*0Sstevel@tonic-gate comp_mask = SA_PR_COMPMASK_SGID | SA_PR_COMPMASK_NUMBPATH;
1080*0Sstevel@tonic-gate
1081*0Sstevel@tonic-gate bzero(&path_record, sizeof (sa_path_record_t));
1082*0Sstevel@tonic-gate
1083*0Sstevel@tonic-gate path_record.SGID = sgid;
1084*0Sstevel@tonic-gate path_record.NumbPath = 1;
1085*0Sstevel@tonic-gate
1086*0Sstevel@tonic-gate if (reversible == B_TRUE) {
1087*0Sstevel@tonic-gate path_record.Reversible = 1;
1088*0Sstevel@tonic-gate comp_mask |= SA_PR_COMPMASK_REVERSIBLE;
1089*0Sstevel@tonic-gate }
1090*0Sstevel@tonic-gate
1091*0Sstevel@tonic-gate if (p_key != IBMF_SAA_PKEY_WC) {
1092*0Sstevel@tonic-gate
1093*0Sstevel@tonic-gate path_record.P_Key = p_key;
1094*0Sstevel@tonic-gate comp_mask |= SA_PR_COMPMASK_PKEY;
1095*0Sstevel@tonic-gate }
1096*0Sstevel@tonic-gate
1097*0Sstevel@tonic-gate access_args.sq_attr_id = SA_PATHRECORD_ATTRID;
1098*0Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
1099*0Sstevel@tonic-gate access_args.sq_component_mask = comp_mask;
1100*0Sstevel@tonic-gate access_args.sq_template = &path_record;
1101*0Sstevel@tonic-gate access_args.sq_callback = NULL;
1102*0Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
1103*0Sstevel@tonic-gate
1104*0Sstevel@tonic-gate res = ibmf_sa_access(ibmf_saa_handle, &access_args, 0, length,
1105*0Sstevel@tonic-gate (void **)result);
1106*0Sstevel@tonic-gate if (res != IBMF_SUCCESS) {
1107*0Sstevel@tonic-gate
1108*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L2,
1109*0Sstevel@tonic-gate ibmf_saa_gid_to_pathrecords, IBMF_TNF_TRACE, "",
1110*0Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords: %s, ibmf_status = %d\n",
1111*0Sstevel@tonic-gate tnf_string, msg, "ibmf_sa_access() failed",
1112*0Sstevel@tonic-gate tnf_int, ibmf_status, res);
1113*0Sstevel@tonic-gate }
1114*0Sstevel@tonic-gate
1115*0Sstevel@tonic-gate *num_paths = *length / sizeof (sa_path_record_t);
1116*0Sstevel@tonic-gate
1117*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
1118*0Sstevel@tonic-gate ibmf_saa_paths_from_gid_end, IBMF_TNF_TRACE, "",
1119*0Sstevel@tonic-gate "ibmf_saa_paths_from_gid() exit: result = 0x%x\n",
1120*0Sstevel@tonic-gate tnf_opaque, result, res);
1121*0Sstevel@tonic-gate
1122*0Sstevel@tonic-gate return (res);
1123*0Sstevel@tonic-gate }
1124*0Sstevel@tonic-gate
1125*0Sstevel@tonic-gate /*
1126*0Sstevel@tonic-gate * ibmf_saa_name_to_service_record:
1127*0Sstevel@tonic-gate * Given a service name, return the service records associated
1128*0Sstevel@tonic-gate * with it.
1129*0Sstevel@tonic-gate *
1130*0Sstevel@tonic-gate * This interface blocks.
1131*0Sstevel@tonic-gate *
1132*0Sstevel@tonic-gate * Input Arguments:
1133*0Sstevel@tonic-gate * ibmf_saa_handle - handle returned from ibmf_sa_session_open()
1134*0Sstevel@tonic-gate * name - service name, a null terminated string
1135*0Sstevel@tonic-gate * p_key - partition that the service is requested on. This
1136*0Sstevel@tonic-gate * value may be wildcarded with IBMF_SAA_PKEY_WC.
1137*0Sstevel@tonic-gate * flags - unused
1138*0Sstevel@tonic-gate *
1139*0Sstevel@tonic-gate * Output Arguments:
1140*0Sstevel@tonic-gate * num_records - number of service records returned
1141*0Sstevel@tonic-gate * length - size of buffer returned
1142*0Sstevel@tonic-gate * result - pointer to buffer of service records returned in
1143*0Sstevel@tonic-gate * response
1144*0Sstevel@tonic-gate * Return values:
1145*0Sstevel@tonic-gate * Error codes are the same as ibmf_sa_access() return values
1146*0Sstevel@tonic-gate *
1147*0Sstevel@tonic-gate * Upon successful completion, result points to a buffer containing the records.
1148*0Sstevel@tonic-gate * and num_records is the number of service records returned. length is the
1149*0Sstevel@tonic-gate * size in bytes of the buffer returned in result. If there are no records or
1150*0Sstevel@tonic-gate * the call failed the length is 0.
1151*0Sstevel@tonic-gate *
1152*0Sstevel@tonic-gate * The consumer is responsible for freeing the memory associated with result.
1153*0Sstevel@tonic-gate */
1154*0Sstevel@tonic-gate /* ARGSUSED */
1155*0Sstevel@tonic-gate int
ibmf_saa_name_to_service_record(ibmf_saa_handle_t ibmf_saa_handle,char * service_name,ib_pkey_t p_key,uint_t flags,uint_t * num_records,size_t * length,sa_service_record_t ** result)1156*0Sstevel@tonic-gate ibmf_saa_name_to_service_record(ibmf_saa_handle_t ibmf_saa_handle,
1157*0Sstevel@tonic-gate char *service_name, ib_pkey_t p_key, uint_t flags,
1158*0Sstevel@tonic-gate uint_t *num_records, size_t *length, sa_service_record_t **result)
1159*0Sstevel@tonic-gate {
1160*0Sstevel@tonic-gate sa_service_record_t service_record;
1161*0Sstevel@tonic-gate int res;
1162*0Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
1163*0Sstevel@tonic-gate
1164*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1165*0Sstevel@tonic-gate ibmf_saa_name_to_service_record_start, IBMF_TNF_TRACE, "",
1166*0Sstevel@tonic-gate "ibmf_saa_name_to_service_record() enter\n");
1167*0Sstevel@tonic-gate
1168*0Sstevel@tonic-gate /* check valid handle; in non-debug system ibmf_sa_access() will fail */
1169*0Sstevel@tonic-gate ASSERT(ibmf_saa_handle != NULL);
1170*0Sstevel@tonic-gate
1171*0Sstevel@tonic-gate ASSERT(num_records != NULL);
1172*0Sstevel@tonic-gate ASSERT(length != NULL);
1173*0Sstevel@tonic-gate ASSERT(result != NULL);
1174*0Sstevel@tonic-gate
1175*0Sstevel@tonic-gate bzero((void *)&service_record, sizeof (sa_service_record_t));
1176*0Sstevel@tonic-gate
1177*0Sstevel@tonic-gate if (strlen(service_name) >= IB_SVC_NAME_LEN) {
1178*0Sstevel@tonic-gate
1179*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
1180*0Sstevel@tonic-gate ibmf_saa_name_to_service_record_err, IBMF_TNF_ERROR, "",
1181*0Sstevel@tonic-gate "ibmf_saa_gid_to_pathrecords: %s, service_name = %s\n",
1182*0Sstevel@tonic-gate tnf_string, msg, "service name too long",
1183*0Sstevel@tonic-gate tnf_string, service_name, service_name);
1184*0Sstevel@tonic-gate
1185*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1186*0Sstevel@tonic-gate ibmf_saa_name_to_service_record_end, IBMF_TNF_TRACE, "",
1187*0Sstevel@tonic-gate "ibmf_saa_name_to_service_record() exit\n");
1188*0Sstevel@tonic-gate
1189*0Sstevel@tonic-gate *num_records = 0;
1190*0Sstevel@tonic-gate *length = 0;
1191*0Sstevel@tonic-gate *result = NULL;
1192*0Sstevel@tonic-gate
1193*0Sstevel@tonic-gate return (IBMF_REQ_INVALID);
1194*0Sstevel@tonic-gate }
1195*0Sstevel@tonic-gate
1196*0Sstevel@tonic-gate /* copy IB_SVC_NAME_LEN bytes, leaving room at end for null char */
1197*0Sstevel@tonic-gate (void) strncpy((char *)(service_record.ServiceName), service_name,
1198*0Sstevel@tonic-gate IB_SVC_NAME_LEN-1);
1199*0Sstevel@tonic-gate
1200*0Sstevel@tonic-gate if (p_key != IBMF_SAA_PKEY_WC) {
1201*0Sstevel@tonic-gate service_record.ServiceP_Key = p_key;
1202*0Sstevel@tonic-gate access_args.sq_component_mask = SA_SR_COMPMASK_NAME |
1203*0Sstevel@tonic-gate SA_SR_COMPMASK_PKEY;
1204*0Sstevel@tonic-gate } else
1205*0Sstevel@tonic-gate access_args.sq_component_mask = SA_SR_COMPMASK_NAME;
1206*0Sstevel@tonic-gate
1207*0Sstevel@tonic-gate access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
1208*0Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
1209*0Sstevel@tonic-gate access_args.sq_template = &service_record;
1210*0Sstevel@tonic-gate access_args.sq_callback = NULL;
1211*0Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
1212*0Sstevel@tonic-gate
1213*0Sstevel@tonic-gate res = ibmf_sa_access(ibmf_saa_handle, &access_args, 0, length,
1214*0Sstevel@tonic-gate (void *)result);
1215*0Sstevel@tonic-gate if (res != IBMF_SUCCESS) {
1216*0Sstevel@tonic-gate
1217*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L2,
1218*0Sstevel@tonic-gate ibmf_saa_name_to_service_record, IBMF_TNF_TRACE, "",
1219*0Sstevel@tonic-gate "ibmf_saa_name_to_service_record: %s, ibmf_status = %d\n",
1220*0Sstevel@tonic-gate tnf_string, msg, "ibmf_sa_access() failed",
1221*0Sstevel@tonic-gate tnf_int, ibmf_status, res);
1222*0Sstevel@tonic-gate }
1223*0Sstevel@tonic-gate
1224*0Sstevel@tonic-gate *num_records = *length / sizeof (sa_service_record_t);
1225*0Sstevel@tonic-gate
1226*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
1227*0Sstevel@tonic-gate ibmf_saa_name_to_service_record_end, IBMF_TNF_TRACE, "",
1228*0Sstevel@tonic-gate "ibmf_saa_name_to_service_record() exit: result = 0x%x\n",
1229*0Sstevel@tonic-gate tnf_opaque, result, res);
1230*0Sstevel@tonic-gate
1231*0Sstevel@tonic-gate return (res);
1232*0Sstevel@tonic-gate }
1233*0Sstevel@tonic-gate
1234*0Sstevel@tonic-gate /*
1235*0Sstevel@tonic-gate * ibmf_saa_id_to_service_record:
1236*0Sstevel@tonic-gate * Given a service id, return the service records associated
1237*0Sstevel@tonic-gate * with it.
1238*0Sstevel@tonic-gate *
1239*0Sstevel@tonic-gate * This interface blocks.
1240*0Sstevel@tonic-gate *
1241*0Sstevel@tonic-gate * Input Arguments:
1242*0Sstevel@tonic-gate * ibmf_saa_handle - handle returned from ibmf_sa_session_open()
1243*0Sstevel@tonic-gate * id - service id
1244*0Sstevel@tonic-gate * p_key - partition that the service is requested on. This
1245*0Sstevel@tonic-gate * value may be wildcarded with IBMF_SAA_PKEY_WC.
1246*0Sstevel@tonic-gate * flags - unused
1247*0Sstevel@tonic-gate *
1248*0Sstevel@tonic-gate * Output Arguments:
1249*0Sstevel@tonic-gate * num_records - number of service records returned
1250*0Sstevel@tonic-gate * length - size of buffer returned
1251*0Sstevel@tonic-gate * result - pointer to buffer of service records returned in
1252*0Sstevel@tonic-gate * response
1253*0Sstevel@tonic-gate *
1254*0Sstevel@tonic-gate * Return values:
1255*0Sstevel@tonic-gate * Error codes are the same as ibmf_sa_access() return values
1256*0Sstevel@tonic-gate *
1257*0Sstevel@tonic-gate * Upon successful completion, result points to a buffer containing the records.
1258*0Sstevel@tonic-gate * and num_records is the number of service records returned. length is the
1259*0Sstevel@tonic-gate * size in bytes of the buffer returned in result. If there are no records or
1260*0Sstevel@tonic-gate * the call failed the length is 0.
1261*0Sstevel@tonic-gate *
1262*0Sstevel@tonic-gate * The consumer is responsible for freeing the memory associated with result.
1263*0Sstevel@tonic-gate */
1264*0Sstevel@tonic-gate /* ARGSUSED */
1265*0Sstevel@tonic-gate int
ibmf_saa_id_to_service_record(ibmf_saa_handle_t ibmf_saa_handle,ib_svc_id_t service_id,ib_pkey_t p_key,uint_t flags,uint_t * num_records,size_t * length,sa_service_record_t ** result)1266*0Sstevel@tonic-gate ibmf_saa_id_to_service_record(ibmf_saa_handle_t ibmf_saa_handle,
1267*0Sstevel@tonic-gate ib_svc_id_t service_id, ib_pkey_t p_key, uint_t flags, uint_t *num_records,
1268*0Sstevel@tonic-gate size_t *length, sa_service_record_t **result)
1269*0Sstevel@tonic-gate {
1270*0Sstevel@tonic-gate sa_service_record_t service_record;
1271*0Sstevel@tonic-gate int res;
1272*0Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
1273*0Sstevel@tonic-gate
1274*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1275*0Sstevel@tonic-gate ibmf_saa_id_to_service_record_start, IBMF_TNF_TRACE, "",
1276*0Sstevel@tonic-gate "ibmf_saa_id_to_service_record() enter\n");
1277*0Sstevel@tonic-gate
1278*0Sstevel@tonic-gate /* check valid handle; in non-debug system ibmf_sa_access() will fail */
1279*0Sstevel@tonic-gate ASSERT(ibmf_saa_handle != NULL);
1280*0Sstevel@tonic-gate
1281*0Sstevel@tonic-gate ASSERT(num_records != NULL);
1282*0Sstevel@tonic-gate ASSERT(length != NULL);
1283*0Sstevel@tonic-gate ASSERT(result != NULL);
1284*0Sstevel@tonic-gate
1285*0Sstevel@tonic-gate bzero((void *)&service_record, sizeof (sa_service_record_t));
1286*0Sstevel@tonic-gate
1287*0Sstevel@tonic-gate service_record.ServiceID = service_id;
1288*0Sstevel@tonic-gate
1289*0Sstevel@tonic-gate if (p_key != IBMF_SAA_PKEY_WC) {
1290*0Sstevel@tonic-gate service_record.ServiceP_Key = p_key;
1291*0Sstevel@tonic-gate access_args.sq_component_mask = SA_SR_COMPMASK_ID |
1292*0Sstevel@tonic-gate SA_SR_COMPMASK_PKEY;
1293*0Sstevel@tonic-gate } else
1294*0Sstevel@tonic-gate access_args.sq_component_mask = SA_SR_COMPMASK_ID;
1295*0Sstevel@tonic-gate
1296*0Sstevel@tonic-gate access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
1297*0Sstevel@tonic-gate access_args.sq_access_type = IBMF_SAA_RETRIEVE;
1298*0Sstevel@tonic-gate access_args.sq_template = &service_record;
1299*0Sstevel@tonic-gate access_args.sq_callback = NULL;
1300*0Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
1301*0Sstevel@tonic-gate
1302*0Sstevel@tonic-gate res = ibmf_sa_access(ibmf_saa_handle, &access_args, 0, length,
1303*0Sstevel@tonic-gate (void **)result);
1304*0Sstevel@tonic-gate if (res != IBMF_SUCCESS) {
1305*0Sstevel@tonic-gate
1306*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L2,
1307*0Sstevel@tonic-gate ibmf_saa_id_to_service_record, IBMF_TNF_TRACE, "",
1308*0Sstevel@tonic-gate "ibmf_saa_id_to_service_record: %s, ibmf_status = %d\n",
1309*0Sstevel@tonic-gate tnf_string, msg, "ibmf_sa_access() failed",
1310*0Sstevel@tonic-gate tnf_int, ibmf_status, res);
1311*0Sstevel@tonic-gate }
1312*0Sstevel@tonic-gate
1313*0Sstevel@tonic-gate *num_records = *length / sizeof (sa_service_record_t);
1314*0Sstevel@tonic-gate
1315*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
1316*0Sstevel@tonic-gate ibmf_saa_id_to_service_record_end, IBMF_TNF_TRACE, "",
1317*0Sstevel@tonic-gate "ibmf_saa_id_to_service_record() exit: result = 0x%x\n",
1318*0Sstevel@tonic-gate tnf_opaque, result, res);
1319*0Sstevel@tonic-gate
1320*0Sstevel@tonic-gate return (res);
1321*0Sstevel@tonic-gate }
1322*0Sstevel@tonic-gate
1323*0Sstevel@tonic-gate /*
1324*0Sstevel@tonic-gate * ibmf_saa_update_service_record
1325*0Sstevel@tonic-gate * Given a pointer to a service record, either insert or delete it
1326*0Sstevel@tonic-gate *
1327*0Sstevel@tonic-gate * This interface blocks.
1328*0Sstevel@tonic-gate *
1329*0Sstevel@tonic-gate * Input Arguments:
1330*0Sstevel@tonic-gate * ibmf_saa_handle - handle returned from ibmf_sa_session_open()
1331*0Sstevel@tonic-gate * service_record - service record is to be inserted or deleted. To
1332*0Sstevel@tonic-gate * delete a service record the GID, ID, P_Key, and
1333*0Sstevel@tonic-gate * Service Key must match what is in the SA.
1334*0Sstevel@tonic-gate * access_type - indicates whether this is an insertion or deletion.
1335*0Sstevel@tonic-gate * valid values are IBMF_SAA_UPDATE or IBMF_SAA_DELETE
1336*0Sstevel@tonic-gate * flags - unused
1337*0Sstevel@tonic-gate *
1338*0Sstevel@tonic-gate * Output Arguments
1339*0Sstevel@tonic-gate * none
1340*0Sstevel@tonic-gate *
1341*0Sstevel@tonic-gate * Return values:
1342*0Sstevel@tonic-gate * Error codes are the same as ibmf_sa_access() return values
1343*0Sstevel@tonic-gate */
1344*0Sstevel@tonic-gate /* ARGSUSED */
1345*0Sstevel@tonic-gate int
ibmf_saa_update_service_record(ibmf_saa_handle_t ibmf_saa_handle,sa_service_record_t * service_record,ibmf_saa_access_type_t access_type,uint_t flags)1346*0Sstevel@tonic-gate ibmf_saa_update_service_record(ibmf_saa_handle_t ibmf_saa_handle,
1347*0Sstevel@tonic-gate sa_service_record_t *service_record, ibmf_saa_access_type_t access_type,
1348*0Sstevel@tonic-gate uint_t flags)
1349*0Sstevel@tonic-gate {
1350*0Sstevel@tonic-gate size_t length;
1351*0Sstevel@tonic-gate void *result;
1352*0Sstevel@tonic-gate int res;
1353*0Sstevel@tonic-gate uint64_t comp_mask;
1354*0Sstevel@tonic-gate ibmf_saa_access_args_t access_args;
1355*0Sstevel@tonic-gate
1356*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1357*0Sstevel@tonic-gate ibmf_saa_update_service_record_start, IBMF_TNF_TRACE, "",
1358*0Sstevel@tonic-gate "ibmf_saa_update_service_record() enter\n");
1359*0Sstevel@tonic-gate
1360*0Sstevel@tonic-gate /* check valid handle; in non-debug system ibmf_sa_access() will fail */
1361*0Sstevel@tonic-gate ASSERT(ibmf_saa_handle != NULL);
1362*0Sstevel@tonic-gate
1363*0Sstevel@tonic-gate if ((access_type != IBMF_SAA_UPDATE) &&
1364*0Sstevel@tonic-gate (access_type != IBMF_SAA_DELETE)) {
1365*0Sstevel@tonic-gate
1366*0Sstevel@tonic-gate IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1,
1367*0Sstevel@tonic-gate ibmf_saa_update_service_record_err, IBMF_TNF_ERROR, "",
1368*0Sstevel@tonic-gate "ibmf_saa_update_service_record: %s, access_type = 0x%x\n",
1369*0Sstevel@tonic-gate tnf_string, msg, "invalid query type",
1370*0Sstevel@tonic-gate tnf_opaque, access_type, access_type);
1371*0Sstevel@tonic-gate
1372*0Sstevel@tonic-gate IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4,
1373*0Sstevel@tonic-gate ibmf_saa_update_service_record_end, IBMF_TNF_TRACE, "",
1374*0Sstevel@tonic-gate "ibmf_saa_update_service_record() exit\n");
1375*0Sstevel@tonic-gate
1376*0Sstevel@tonic-gate return (IBMF_REQ_INVALID);
1377*0Sstevel@tonic-gate }
1378*0Sstevel@tonic-gate
1379*0Sstevel@tonic-gate /*
1380*0Sstevel@tonic-gate * call ibmf_sa_access with the following special parameters:
1381*0Sstevel@tonic-gate * attrid : service_record
1382*0Sstevel@tonic-gate * component_mask : RID fields of service record (GID, ID, and P_key)
1383*0Sstevel@tonic-gate * and service key
1384*0Sstevel@tonic-gate */
1385*0Sstevel@tonic-gate comp_mask = SA_SR_COMPMASK_ID | SA_SR_COMPMASK_GID |
1386*0Sstevel@tonic-gate SA_SR_COMPMASK_PKEY | SA_SR_COMPMASK_KEY;
1387*0Sstevel@tonic-gate
1388*0Sstevel@tonic-gate access_args.sq_attr_id = SA_SERVICERECORD_ATTRID;
1389*0Sstevel@tonic-gate access_args.sq_access_type = access_type;
1390*0Sstevel@tonic-gate access_args.sq_component_mask = comp_mask;
1391*0Sstevel@tonic-gate access_args.sq_template = service_record;
1392*0Sstevel@tonic-gate access_args.sq_callback = NULL;
1393*0Sstevel@tonic-gate access_args.sq_callback_arg = NULL;
1394*0Sstevel@tonic-gate
1395*0Sstevel@tonic-gate res = ibmf_sa_access(ibmf_saa_handle, &access_args, 0, &length,
1396*0Sstevel@tonic-gate &result);
1397*0Sstevel@tonic-gate
1398*0Sstevel@tonic-gate /* if a valid add request, response buffer should be one service rec */
1399*0Sstevel@tonic-gate if (res == IBMF_SUCCESS && length > 0) {
1400*0Sstevel@tonic-gate
1401*0Sstevel@tonic-gate if (length > sizeof (sa_service_record_t)) {
1402*0Sstevel@tonic-gate
1403*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L1,
1404*0Sstevel@tonic-gate ibmf_saa_update_service_record, IBMF_TNF_TRACE, "",
1405*0Sstevel@tonic-gate "ibmf_saa_update_service_record: %s\n",
1406*0Sstevel@tonic-gate tnf_string, msg,
1407*0Sstevel@tonic-gate "SA returned more than one record");
1408*0Sstevel@tonic-gate }
1409*0Sstevel@tonic-gate
1410*0Sstevel@tonic-gate kmem_free(result, length);
1411*0Sstevel@tonic-gate }
1412*0Sstevel@tonic-gate
1413*0Sstevel@tonic-gate IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L3,
1414*0Sstevel@tonic-gate ibmf_saa_update_service_record_end, IBMF_TNF_TRACE, "",
1415*0Sstevel@tonic-gate "ibmf_saa_update_service_record() exit: result = 0x%x\n",
1416*0Sstevel@tonic-gate tnf_opaque, result, res);
1417*0Sstevel@tonic-gate
1418*0Sstevel@tonic-gate return (res);
1419*0Sstevel@tonic-gate }
1420