xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_kdoor.c (revision 8622ec4569457733001d4982ef7f5b44427069be)
19fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
29fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * CDDL HEADER START
39fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
49fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The contents of this file are subject to the terms of the
59fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Common Development and Distribution License (the "License").
69fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * You may not use this file except in compliance with the License.
79fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
89fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * or http://www.opensolaris.org/os/licensing.
109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * See the License for the specific language governing permissions
119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and limitations under the License.
129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * When distributing Covered Code, include this CDDL HEADER in each
149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If applicable, add the following below this CDDL HEADER, with the
169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * fields enclosed by brackets "[]" replaced with your own identifying
179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * information: Portions Copyright [yyyy] [name of copyright owner]
189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * CDDL HEADER END
209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
22*8622ec45SGordon Ross  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23cb174861Sjoyce mcintosh  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/types.h>
279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/kmem.h>
289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/ddi.h>
299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/sunddi.h>
309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/cmn_err.h>
319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/door.h>
329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_kproto.h>
339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h>
349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
35*8622ec45SGordon Ross static int smb_kdoor_send(smb_server_t *, smb_doorarg_t *);
36*8622ec45SGordon Ross static int smb_kdoor_receive(smb_server_t *, smb_doorarg_t *);
37*8622ec45SGordon Ross static int smb_kdoor_upcall_private(smb_server_t *, smb_doorarg_t *);
389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_kdoor_encode(smb_doorarg_t *);
399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_kdoor_decode(smb_doorarg_t *);
409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_kdoor_sethdr(smb_doorarg_t *, uint32_t);
419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t smb_kdoor_chkhdr(smb_doorarg_t *, smb_doorhdr_t *);
429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_kdoor_free(door_arg_t *);
439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
45*8622ec45SGordon Ross smb_kdoor_init(smb_server_t *sv)
469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
47*8622ec45SGordon Ross 	sv->sv_kdoor_id = -1;
48*8622ec45SGordon Ross 	mutex_init(&sv->sv_kdoor_mutex, NULL, MUTEX_DEFAULT, NULL);
49*8622ec45SGordon Ross 	cv_init(&sv->sv_kdoor_cv, NULL, CV_DEFAULT, NULL);
509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
53*8622ec45SGordon Ross smb_kdoor_fini(smb_server_t *sv)
549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
55*8622ec45SGordon Ross 	smb_kdoor_close(sv);
56*8622ec45SGordon Ross 	cv_destroy(&sv->sv_kdoor_cv);
57*8622ec45SGordon Ross 	mutex_destroy(&sv->sv_kdoor_mutex);
589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Open the door.  If the door is already open, close it first
629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * because the door-id has probably changed.
639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
65*8622ec45SGordon Ross smb_kdoor_open(smb_server_t *sv, int door_id)
669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc;
689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
69*8622ec45SGordon Ross 	smb_kdoor_close(sv);
709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
71*8622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
72*8622ec45SGordon Ross 	sv->sv_kdoor_ncall = 0;
739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
74*8622ec45SGordon Ross 	if (sv->sv_kdoor_hd == NULL) {
75*8622ec45SGordon Ross 		sv->sv_kdoor_id = door_id;
76*8622ec45SGordon Ross 		sv->sv_kdoor_hd = door_ki_lookup(door_id);
779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
79*8622ec45SGordon Ross 	rc = (sv->sv_kdoor_hd == NULL)  ? -1 : 0;
80*8622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Close the door.
869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
88*8622ec45SGordon Ross smb_kdoor_close(smb_server_t *sv)
899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
90*8622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
92*8622ec45SGordon Ross 	if (sv->sv_kdoor_hd != NULL) {
93*8622ec45SGordon Ross 		while (sv->sv_kdoor_ncall > 0)
94*8622ec45SGordon Ross 			cv_wait(&sv->sv_kdoor_cv, &sv->sv_kdoor_mutex);
959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
96*8622ec45SGordon Ross 		door_ki_rele(sv->sv_kdoor_hd);
97*8622ec45SGordon Ross 		sv->sv_kdoor_hd = NULL;
98*8622ec45SGordon Ross 		sv->sv_kdoor_id = -1;
999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
101*8622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
1029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Wrapper to handle door call reference counting.
1069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
108*8622ec45SGordon Ross smb_kdoor_upcall(smb_server_t *sv, uint32_t cmd,
109*8622ec45SGordon Ross     void *req_data, xdrproc_t req_xdr,
1109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void *rsp_data, xdrproc_t rsp_xdr)
1119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorarg_t	da;
1139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
1149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(&da, sizeof (smb_doorarg_t));
1169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opcode = cmd;
1179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opname = smb_doorhdr_opname(cmd);
1189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_xdr = req_xdr;
1199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_xdr = rsp_xdr;
1209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_data = req_data;
1219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_data = rsp_data;
1229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((req_data == NULL && req_xdr != NULL) ||
1249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (rsp_data == NULL && rsp_xdr != NULL)) {
1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_upcall[%s]: invalid param",
1269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da.da_opname);
1279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
1289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rsp_data != NULL && rsp_xdr != NULL)
1319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		da.da_flags = SMB_DF_ASYNC;
1329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
133*8622ec45SGordon Ross 	if ((da.da_event = smb_event_create(sv, SMB_EVENT_TIMEOUT)) == NULL)
1349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
1359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
136*8622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
1379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
138*8622ec45SGordon Ross 	if (sv->sv_kdoor_hd == NULL) {
139*8622ec45SGordon Ross 		mutex_exit(&sv->sv_kdoor_mutex);
1409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
141*8622ec45SGordon Ross 		if (smb_kdoor_open(sv, sv->sv_kdoor_id) != 0) {
1429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_event_destroy(da.da_event);
1439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
1449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
146*8622ec45SGordon Ross 		mutex_enter(&sv->sv_kdoor_mutex);
1479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
149*8622ec45SGordon Ross 	sv->sv_kdoor_ncall++;
150*8622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
1519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (da.da_flags & SMB_DF_ASYNC) {
153*8622ec45SGordon Ross 		if ((rc = smb_kdoor_send(sv, &da)) == 0) {
1549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (smb_event_wait(da.da_event) != 0)
1559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				rc = -1;
1569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			else
157*8622ec45SGordon Ross 				rc = smb_kdoor_receive(sv, &da);
1589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
1609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((rc = smb_kdoor_encode(&da)) == 0) {
161*8622ec45SGordon Ross 			if ((rc = smb_kdoor_upcall_private(sv, &da)) == 0)
1629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				rc = smb_kdoor_decode(&da);
1639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_kdoor_free(&da.da_arg);
1659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_event_destroy(da.da_event);
1689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
169*8622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
170*8622ec45SGordon Ross 	if ((--sv->sv_kdoor_ncall) == 0)
171*8622ec45SGordon Ross 		cv_signal(&sv->sv_kdoor_cv);
172*8622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Send the request half of the consumer's door call.
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
180*8622ec45SGordon Ross smb_kdoor_send(smb_server_t *sv, smb_doorarg_t *outer_da)
1819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorarg_t	da;
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(outer_da, &da, sizeof (smb_doorarg_t));
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_xdr = NULL;
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_data = NULL;
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_kdoor_encode(&da) != 0)
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
192*8622ec45SGordon Ross 	if ((rc = smb_kdoor_upcall_private(sv, &da)) == 0)
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smb_kdoor_decode(&da);
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_free(&da.da_arg);
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Get the response half for the consumer's door call.
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
203*8622ec45SGordon Ross smb_kdoor_receive(smb_server_t *sv, smb_doorarg_t *outer_da)
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorarg_t	da;
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(outer_da, &da, sizeof (smb_doorarg_t));
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opcode = SMB_DR_ASYNC_RESPONSE;
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opname = smb_doorhdr_opname(da.da_opcode);
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_flags &= ~SMB_DF_ASYNC;
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_xdr = NULL;
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_data = NULL;
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_kdoor_encode(&da) != 0)
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
218*8622ec45SGordon Ross 	if ((rc = smb_kdoor_upcall_private(sv, &da)) == 0)
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smb_kdoor_decode(&da);
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_free(&da.da_arg);
2229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * We use a copy of the door arg because doorfs may change data_ptr
2279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and we want to detect that when freeing the door buffers.  After
2289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * this call, response data must be referenced via rbuf and rsize.
2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
231*8622ec45SGordon Ross smb_kdoor_upcall_private(smb_server_t *sv, smb_doorarg_t *da)
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	door_arg_t	door_arg;
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i;
2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
2369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(&da->da_arg, &door_arg, sizeof (door_arg_t));
2389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < SMB_DOOR_CALL_RETRIES; ++i) {
240*8622ec45SGordon Ross 		if (smb_server_is_stopping(sv))
2419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
2429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
243*8622ec45SGordon Ross 		if ((rc = door_ki_upcall_limited(sv->sv_kdoor_hd, &door_arg,
2449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    NULL, SIZE_MAX, 0)) == 0)
2459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
2469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != EAGAIN && rc != EINTR)
2489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
2499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != 0 || door_arg.data_size == 0 || door_arg.rsize == 0)
2529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
2539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rbuf = door_arg.data_ptr;
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rsize = door_arg.rsize;
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_encode(smb_doorarg_t *da)
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	XDR		xdrs;
2639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*buf;
2649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	len;
2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	len = xdr_sizeof(smb_doorhdr_xdr, &da->da_hdr);
2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (da->da_req_xdr != NULL)
2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		len += xdr_sizeof(da->da_req_xdr, da->da_req_data);
2699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_sethdr(da, len);
2719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	buf = kmem_zalloc(len, KM_SLEEP);
2739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdrmem_create(&xdrs, buf, len, XDR_ENCODE);
2749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_doorhdr_xdr(&xdrs, &da->da_hdr)) {
2769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_encode[%s]: header encode failed",
2779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
2789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(buf, len);
2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		xdr_destroy(&xdrs);
2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
2819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (da->da_req_xdr != NULL) {
2849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!da->da_req_xdr(&xdrs, da->da_req_data)) {
2859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "smb_kdoor_encode[%s]: encode failed",
2869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    da->da_opname);
2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			kmem_free(buf, len);
2889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			xdr_destroy(&xdrs);
2899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
2909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
2919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.data_ptr = buf;
2949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.data_size = len;
2959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.desc_ptr = NULL;
2969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.desc_num = 0;
2979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rbuf = buf;
2989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rsize = len;
2999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdr_destroy(&xdrs);
3019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
3029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Decode the response in rbuf and rsize.
3069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_decode(smb_doorarg_t *da)
3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	XDR		xdrs;
3119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorhdr_t	hdr;
3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*rbuf = da->da_arg.rbuf;
3139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	rsize = da->da_arg.rsize;
3149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rbuf == NULL || rsize == 0) {
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_decode[%s]: invalid param",
3179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
3189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdrmem_create(&xdrs, rbuf, rsize, XDR_DECODE);
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_doorhdr_xdr(&xdrs, &hdr)) {
3249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_decode[%s]: header decode failed",
3259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
3269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		xdr_destroy(&xdrs);
3279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_kdoor_chkhdr(da, &hdr)) {
3319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		xdr_destroy(&xdrs);
3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (hdr.dh_datalen != 0 && da->da_rsp_xdr != NULL) {
3369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!da->da_rsp_xdr(&xdrs, da->da_rsp_data)) {
3379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "smb_kdoor_decode[%s]: decode failed",
3389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    da->da_opname);
3399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			xdr_destroy(&xdrs);
3409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
3419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
3429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdr_destroy(&xdrs);
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_sethdr(smb_doorarg_t *da, uint32_t datalen)
3509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorhdr_t	*hdr = &da->da_hdr;
3529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(hdr, sizeof (smb_doorhdr_t));
3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_magic = SMB_DOOR_HDR_MAGIC;
3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_flags = da->da_flags | SMB_DF_SYSSPACE;
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_op = da->da_opcode;
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_txid = smb_event_txid(da->da_event);
3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_datalen = datalen;
3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_door_rc = SMB_DOP_NOT_CALLED;
3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t
3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_chkhdr(smb_doorarg_t *da, smb_doorhdr_t *hdr)
3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((hdr->dh_magic != SMB_DOOR_HDR_MAGIC) ||
3669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (hdr->dh_op != da->da_hdr.dh_op) ||
3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (hdr->dh_txid != da->da_hdr.dh_txid)) {
3689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_chkhdr[%s]: invalid header",
3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
373*8622ec45SGordon Ross 	switch (hdr->dh_door_rc) {
374*8622ec45SGordon Ross 	case SMB_DOP_SUCCESS:
375*8622ec45SGordon Ross 		break;
376*8622ec45SGordon Ross 
377*8622ec45SGordon Ross 	/* SMB_DOP_EMPTYBUF is a "normal" error (silent). */
378*8622ec45SGordon Ross 	case SMB_DOP_EMPTYBUF:
379*8622ec45SGordon Ross 		return (B_FALSE);
380*8622ec45SGordon Ross 
381*8622ec45SGordon Ross 	default:
3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_chkhdr[%s]: call failed: %u",
3839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname, hdr->dh_door_rc);
3849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
3859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (B_TRUE);
3889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Free both the argument and result door buffers regardless of the status
3929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * of the up-call.  The doorfs allocates a new buffer if the result buffer
3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * passed by the client is too small.
3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_free(door_arg_t *arg)
3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (arg->rbuf != NULL && arg->rbuf != arg->data_ptr)
3999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(arg->rbuf, arg->rsize);
4009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (arg->data_ptr != NULL)
4029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(arg->data_ptr, arg->data_size);
4039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
404