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 /*
22cb174861Sjoyce mcintosh  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*b819cea2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  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*b819cea2SGordon Ross #ifdef	_FAKE_KERNEL
36*b819cea2SGordon Ross #error	"See libfksmbsrv"
37*b819cea2SGordon Ross #endif	/* _FAKE_KERNEL */
38*b819cea2SGordon Ross 
398622ec45SGordon Ross static int smb_kdoor_send(smb_server_t *, smb_doorarg_t *);
408622ec45SGordon Ross static int smb_kdoor_receive(smb_server_t *, smb_doorarg_t *);
418622ec45SGordon Ross static int smb_kdoor_upcall_private(smb_server_t *, smb_doorarg_t *);
429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_kdoor_encode(smb_doorarg_t *);
439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_kdoor_decode(smb_doorarg_t *);
449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_kdoor_sethdr(smb_doorarg_t *, uint32_t);
459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t smb_kdoor_chkhdr(smb_doorarg_t *, smb_doorhdr_t *);
469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_kdoor_free(door_arg_t *);
479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_kdoor_init(smb_server_t * sv)498622ec45SGordon Ross smb_kdoor_init(smb_server_t *sv)
509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
518622ec45SGordon Ross 	sv->sv_kdoor_id = -1;
528622ec45SGordon Ross 	mutex_init(&sv->sv_kdoor_mutex, NULL, MUTEX_DEFAULT, NULL);
538622ec45SGordon Ross 	cv_init(&sv->sv_kdoor_cv, NULL, CV_DEFAULT, NULL);
549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_kdoor_fini(smb_server_t * sv)578622ec45SGordon Ross smb_kdoor_fini(smb_server_t *sv)
589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
598622ec45SGordon Ross 	smb_kdoor_close(sv);
608622ec45SGordon Ross 	cv_destroy(&sv->sv_kdoor_cv);
618622ec45SGordon Ross 	mutex_destroy(&sv->sv_kdoor_mutex);
629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Open the door.  If the door is already open, close it first
669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * because the door-id has probably changed.
679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_kdoor_open(smb_server_t * sv,int door_id)698622ec45SGordon Ross smb_kdoor_open(smb_server_t *sv, int door_id)
709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc;
729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
738622ec45SGordon Ross 	smb_kdoor_close(sv);
749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
758622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
768622ec45SGordon Ross 	sv->sv_kdoor_ncall = 0;
779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
788622ec45SGordon Ross 	if (sv->sv_kdoor_hd == NULL) {
798622ec45SGordon Ross 		sv->sv_kdoor_id = door_id;
808622ec45SGordon Ross 		sv->sv_kdoor_hd = door_ki_lookup(door_id);
819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
838622ec45SGordon Ross 	rc = (sv->sv_kdoor_hd == NULL)  ? -1 : 0;
848622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Close the door.
909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_kdoor_close(smb_server_t * sv)928622ec45SGordon Ross smb_kdoor_close(smb_server_t *sv)
939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
948622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
968622ec45SGordon Ross 	if (sv->sv_kdoor_hd != NULL) {
978622ec45SGordon Ross 		while (sv->sv_kdoor_ncall > 0)
988622ec45SGordon Ross 			cv_wait(&sv->sv_kdoor_cv, &sv->sv_kdoor_mutex);
999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1008622ec45SGordon Ross 		door_ki_rele(sv->sv_kdoor_hd);
1018622ec45SGordon Ross 		sv->sv_kdoor_hd = NULL;
1028622ec45SGordon Ross 		sv->sv_kdoor_id = -1;
1039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1058622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
1069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Wrapper to handle door call reference counting.
1109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_kdoor_upcall(smb_server_t * sv,uint32_t cmd,void * req_data,xdrproc_t req_xdr,void * rsp_data,xdrproc_t rsp_xdr)1128622ec45SGordon Ross smb_kdoor_upcall(smb_server_t *sv, uint32_t cmd,
1138622ec45SGordon Ross     void *req_data, xdrproc_t req_xdr,
1149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void *rsp_data, xdrproc_t rsp_xdr)
1159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorarg_t	da;
1179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
1189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(&da, sizeof (smb_doorarg_t));
1209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opcode = cmd;
1219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opname = smb_doorhdr_opname(cmd);
1229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_xdr = req_xdr;
1239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_xdr = rsp_xdr;
1249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_data = req_data;
1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_data = rsp_data;
1269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((req_data == NULL && req_xdr != NULL) ||
1289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (rsp_data == NULL && rsp_xdr != NULL)) {
1299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_upcall[%s]: invalid param",
1309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da.da_opname);
1319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
1329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rsp_data != NULL && rsp_xdr != NULL)
1359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		da.da_flags = SMB_DF_ASYNC;
1369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1378622ec45SGordon Ross 	if ((da.da_event = smb_event_create(sv, SMB_EVENT_TIMEOUT)) == NULL)
1389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
1399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1408622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
1419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1428622ec45SGordon Ross 	if (sv->sv_kdoor_hd == NULL) {
1438622ec45SGordon Ross 		mutex_exit(&sv->sv_kdoor_mutex);
1449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1458622ec45SGordon Ross 		if (smb_kdoor_open(sv, sv->sv_kdoor_id) != 0) {
1469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_event_destroy(da.da_event);
1479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
1489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1508622ec45SGordon Ross 		mutex_enter(&sv->sv_kdoor_mutex);
1519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1538622ec45SGordon Ross 	sv->sv_kdoor_ncall++;
1548622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
1559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (da.da_flags & SMB_DF_ASYNC) {
1578622ec45SGordon Ross 		if ((rc = smb_kdoor_send(sv, &da)) == 0) {
1589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (smb_event_wait(da.da_event) != 0)
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				rc = -1;
1609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			else
1618622ec45SGordon Ross 				rc = smb_kdoor_receive(sv, &da);
1629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
1649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((rc = smb_kdoor_encode(&da)) == 0) {
1658622ec45SGordon Ross 			if ((rc = smb_kdoor_upcall_private(sv, &da)) == 0)
1669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				rc = smb_kdoor_decode(&da);
1679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_kdoor_free(&da.da_arg);
1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_event_destroy(da.da_event);
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1738622ec45SGordon Ross 	mutex_enter(&sv->sv_kdoor_mutex);
1748622ec45SGordon Ross 	if ((--sv->sv_kdoor_ncall) == 0)
1758622ec45SGordon Ross 		cv_signal(&sv->sv_kdoor_cv);
1768622ec45SGordon Ross 	mutex_exit(&sv->sv_kdoor_mutex);
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Send the request half of the consumer's door call.
1829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_kdoor_send(smb_server_t * sv,smb_doorarg_t * outer_da)1848622ec45SGordon Ross smb_kdoor_send(smb_server_t *sv, smb_doorarg_t *outer_da)
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorarg_t	da;
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(outer_da, &da, sizeof (smb_doorarg_t));
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_xdr = NULL;
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_rsp_data = NULL;
1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_kdoor_encode(&da) != 0)
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1968622ec45SGordon Ross 	if ((rc = smb_kdoor_upcall_private(sv, &da)) == 0)
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smb_kdoor_decode(&da);
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_free(&da.da_arg);
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Get the response half for the consumer's door call.
2059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_kdoor_receive(smb_server_t * sv,smb_doorarg_t * outer_da)2078622ec45SGordon Ross smb_kdoor_receive(smb_server_t *sv, smb_doorarg_t *outer_da)
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorarg_t	da;
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(outer_da, &da, sizeof (smb_doorarg_t));
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opcode = SMB_DR_ASYNC_RESPONSE;
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_opname = smb_doorhdr_opname(da.da_opcode);
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_flags &= ~SMB_DF_ASYNC;
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_xdr = NULL;
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da.da_req_data = NULL;
2189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_kdoor_encode(&da) != 0)
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
2219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2228622ec45SGordon Ross 	if ((rc = smb_kdoor_upcall_private(sv, &da)) == 0)
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smb_kdoor_decode(&da);
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_free(&da.da_arg);
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
2279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * We use a copy of the door arg because doorfs may change data_ptr
2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and we want to detect that when freeing the door buffers.  After
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * this call, response data must be referenced via rbuf and rsize.
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_kdoor_upcall_private(smb_server_t * sv,smb_doorarg_t * da)2358622ec45SGordon Ross smb_kdoor_upcall_private(smb_server_t *sv, smb_doorarg_t *da)
2369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	door_arg_t	door_arg;
2389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i;
2399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
2409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(&da->da_arg, &door_arg, sizeof (door_arg_t));
2429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < SMB_DOOR_CALL_RETRIES; ++i) {
2448622ec45SGordon Ross 		if (smb_server_is_stopping(sv))
2459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
2469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2478622ec45SGordon Ross 		if ((rc = door_ki_upcall_limited(sv->sv_kdoor_hd, &door_arg,
2489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    NULL, SIZE_MAX, 0)) == 0)
2499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
2509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != EAGAIN && rc != EINTR)
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 
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != 0 || door_arg.data_size == 0 || door_arg.rsize == 0)
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rbuf = door_arg.data_ptr;
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rsize = door_arg.rsize;
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_kdoor_encode(smb_doorarg_t * da)2649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_encode(smb_doorarg_t *da)
2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	XDR		xdrs;
2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*buf;
2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	len;
2699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	len = xdr_sizeof(smb_doorhdr_xdr, &da->da_hdr);
2719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (da->da_req_xdr != NULL)
2729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		len += xdr_sizeof(da->da_req_xdr, da->da_req_data);
2739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_sethdr(da, len);
2759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	buf = kmem_zalloc(len, KM_SLEEP);
2779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdrmem_create(&xdrs, buf, len, XDR_ENCODE);
2789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_doorhdr_xdr(&xdrs, &da->da_hdr)) {
2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_encode[%s]: header encode failed",
2819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
2829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(buf, len);
2839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		xdr_destroy(&xdrs);
2849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
2859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (da->da_req_xdr != NULL) {
2889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!da->da_req_xdr(&xdrs, da->da_req_data)) {
2899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "smb_kdoor_encode[%s]: encode failed",
2909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    da->da_opname);
2919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			kmem_free(buf, len);
2929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			xdr_destroy(&xdrs);
2939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
2949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
2959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.data_ptr = buf;
2989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.data_size = len;
2999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.desc_ptr = NULL;
3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.desc_num = 0;
3019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rbuf = buf;
3029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	da->da_arg.rsize = len;
3039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdr_destroy(&xdrs);
3059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
3069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Decode the response in rbuf and rsize.
3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_kdoor_decode(smb_doorarg_t * da)3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_decode(smb_doorarg_t *da)
3139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	XDR		xdrs;
3159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorhdr_t	hdr;
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*rbuf = da->da_arg.rbuf;
3179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	rsize = da->da_arg.rsize;
3189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rbuf == NULL || rsize == 0) {
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_decode[%s]: invalid param",
3219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdrmem_create(&xdrs, rbuf, rsize, XDR_DECODE);
3269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_doorhdr_xdr(&xdrs, &hdr)) {
3289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_decode[%s]: header decode failed",
3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
3309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		xdr_destroy(&xdrs);
3319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_kdoor_chkhdr(da, &hdr)) {
3359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		xdr_destroy(&xdrs);
3369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (hdr.dh_datalen != 0 && da->da_rsp_xdr != NULL) {
3409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!da->da_rsp_xdr(&xdrs, da->da_rsp_data)) {
3419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "smb_kdoor_decode[%s]: decode failed",
3429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    da->da_opname);
3439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			xdr_destroy(&xdrs);
3449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (-1);
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	xdr_destroy(&xdrs);
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
3509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
smb_kdoor_sethdr(smb_doorarg_t * da,uint32_t datalen)3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_sethdr(smb_doorarg_t *da, uint32_t datalen)
3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_doorhdr_t	*hdr = &da->da_hdr;
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(hdr, sizeof (smb_doorhdr_t));
3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_magic = SMB_DOOR_HDR_MAGIC;
3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_flags = da->da_flags | SMB_DF_SYSSPACE;
3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_op = da->da_opcode;
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_txid = smb_event_txid(da->da_event);
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_datalen = datalen;
3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr->dh_door_rc = SMB_DOP_NOT_CALLED;
3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t
smb_kdoor_chkhdr(smb_doorarg_t * da,smb_doorhdr_t * hdr)3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_chkhdr(smb_doorarg_t *da, smb_doorhdr_t *hdr)
3689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((hdr->dh_magic != SMB_DOOR_HDR_MAGIC) ||
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (hdr->dh_op != da->da_hdr.dh_op) ||
3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (hdr->dh_txid != da->da_hdr.dh_txid)) {
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_chkhdr[%s]: invalid header",
3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname);
3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3778622ec45SGordon Ross 	switch (hdr->dh_door_rc) {
3788622ec45SGordon Ross 	case SMB_DOP_SUCCESS:
3798622ec45SGordon Ross 		break;
3808622ec45SGordon Ross 
3818622ec45SGordon Ross 	/* SMB_DOP_EMPTYBUF is a "normal" error (silent). */
3828622ec45SGordon Ross 	case SMB_DOP_EMPTYBUF:
3838622ec45SGordon Ross 		return (B_FALSE);
3848622ec45SGordon Ross 
3858622ec45SGordon Ross 	default:
3869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_WARN, "smb_kdoor_chkhdr[%s]: call failed: %u",
3879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    da->da_opname, hdr->dh_door_rc);
3889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
3899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (B_TRUE);
3929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Free both the argument and result door buffers regardless of the status
3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * of the up-call.  The doorfs allocates a new buffer if the result buffer
3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * passed by the client is too small.
3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
smb_kdoor_free(door_arg_t * arg)4009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kdoor_free(door_arg_t *arg)
4019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (arg->rbuf != NULL && arg->rbuf != arg->data_ptr)
4039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(arg->rbuf, arg->rsize);
4049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (arg->data_ptr != NULL)
4069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(arg->data_ptr, arg->data_size);
4079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
408