xref: /onnv-gate/usr/src/uts/common/io/ib/clients/iser/iser.c (revision 10322:ba47e44899a2)
19162SPeter.Dunlap@Sun.COM /*
29162SPeter.Dunlap@Sun.COM  * CDDL HEADER START
39162SPeter.Dunlap@Sun.COM  *
49162SPeter.Dunlap@Sun.COM  * The contents of this file are subject to the terms of the
59162SPeter.Dunlap@Sun.COM  * Common Development and Distribution License (the "License").
69162SPeter.Dunlap@Sun.COM  * You may not use this file except in compliance with the License.
79162SPeter.Dunlap@Sun.COM  *
89162SPeter.Dunlap@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99162SPeter.Dunlap@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109162SPeter.Dunlap@Sun.COM  * See the License for the specific language governing permissions
119162SPeter.Dunlap@Sun.COM  * and limitations under the License.
129162SPeter.Dunlap@Sun.COM  *
139162SPeter.Dunlap@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149162SPeter.Dunlap@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159162SPeter.Dunlap@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169162SPeter.Dunlap@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179162SPeter.Dunlap@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189162SPeter.Dunlap@Sun.COM  *
199162SPeter.Dunlap@Sun.COM  * CDDL HEADER END
209162SPeter.Dunlap@Sun.COM  */
219162SPeter.Dunlap@Sun.COM /*
229162SPeter.Dunlap@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
239162SPeter.Dunlap@Sun.COM  * Use is subject to license terms.
249162SPeter.Dunlap@Sun.COM  */
259162SPeter.Dunlap@Sun.COM 
269162SPeter.Dunlap@Sun.COM #include <sys/types.h>
279162SPeter.Dunlap@Sun.COM #include <sys/stat.h>
289162SPeter.Dunlap@Sun.COM #include <sys/conf.h>
299162SPeter.Dunlap@Sun.COM #include <sys/ddi.h>
309162SPeter.Dunlap@Sun.COM #include <sys/sunddi.h>
319162SPeter.Dunlap@Sun.COM #include <sys/modctl.h>
329162SPeter.Dunlap@Sun.COM #include <sys/socket.h>
339162SPeter.Dunlap@Sun.COM #include <netinet/in.h>
349162SPeter.Dunlap@Sun.COM 
359162SPeter.Dunlap@Sun.COM #include <sys/ib/clients/iser/iser.h>
369162SPeter.Dunlap@Sun.COM 
379162SPeter.Dunlap@Sun.COM /*
389162SPeter.Dunlap@Sun.COM  * iser.c
399162SPeter.Dunlap@Sun.COM  *    DDI and core routines for Solaris iSER implementation.
409162SPeter.Dunlap@Sun.COM  */
419162SPeter.Dunlap@Sun.COM 
429162SPeter.Dunlap@Sun.COM iser_state_t	*iser_state = NULL;	/* global state */
439162SPeter.Dunlap@Sun.COM ddi_taskq_t	*iser_taskq = NULL;	/* global taskq */
449162SPeter.Dunlap@Sun.COM 
459162SPeter.Dunlap@Sun.COM /* set B_TRUE for console logging */
469162SPeter.Dunlap@Sun.COM boolean_t iser_logging = B_FALSE;
479162SPeter.Dunlap@Sun.COM 
489162SPeter.Dunlap@Sun.COM /* Driver functions */
499162SPeter.Dunlap@Sun.COM static int iser_attach(dev_info_t *, ddi_attach_cmd_t);
509162SPeter.Dunlap@Sun.COM static int iser_detach(dev_info_t *, ddi_detach_cmd_t);
519162SPeter.Dunlap@Sun.COM static int iser_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
529162SPeter.Dunlap@Sun.COM static int iser_open(dev_t *, int, int, cred_t *);
539162SPeter.Dunlap@Sun.COM static int iser_close(dev_t, int, int, cred_t *);
549162SPeter.Dunlap@Sun.COM static int iser_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
559162SPeter.Dunlap@Sun.COM /* static int iser_close(dev_t, int, int, cred_t *); */
569162SPeter.Dunlap@Sun.COM 
579162SPeter.Dunlap@Sun.COM /* Char/Block operations */
589162SPeter.Dunlap@Sun.COM static struct cb_ops	iser_cb_ops = {
599162SPeter.Dunlap@Sun.COM 	iser_open,		/* open */
609162SPeter.Dunlap@Sun.COM 	iser_close,		/* close */
619162SPeter.Dunlap@Sun.COM 	nodev,			/* strategy */
629162SPeter.Dunlap@Sun.COM 	nodev,			/* print */
639162SPeter.Dunlap@Sun.COM 	nodev,			/* dump */
649162SPeter.Dunlap@Sun.COM 	nodev,			/* read */
659162SPeter.Dunlap@Sun.COM 	nodev,			/* write */
669162SPeter.Dunlap@Sun.COM 	iser_ioctl,		/* ioctl */
679162SPeter.Dunlap@Sun.COM 	nodev,			/* devmap */
689162SPeter.Dunlap@Sun.COM 	nodev,			/* mmap */
699162SPeter.Dunlap@Sun.COM 	nodev,			/* segmap */
709162SPeter.Dunlap@Sun.COM 	nochpoll,		/* poll */
719162SPeter.Dunlap@Sun.COM 	ddi_prop_op,		/* prop_op */
729162SPeter.Dunlap@Sun.COM 	NULL,			/* stream */
739162SPeter.Dunlap@Sun.COM 	D_MP,			/* cb_flag */
749162SPeter.Dunlap@Sun.COM 	CB_REV,			/* rev */
759162SPeter.Dunlap@Sun.COM 	nodev,			/* int (*cb_aread)() */
769162SPeter.Dunlap@Sun.COM 	nodev,			/* int (*cb_awrite)() */
779162SPeter.Dunlap@Sun.COM };
789162SPeter.Dunlap@Sun.COM 
799162SPeter.Dunlap@Sun.COM /* Device operations */
809162SPeter.Dunlap@Sun.COM static struct dev_ops iser_ops = {
819162SPeter.Dunlap@Sun.COM 	DEVO_REV,		/* devo_rev, */
829162SPeter.Dunlap@Sun.COM 	0,			/* refcnt  */
839162SPeter.Dunlap@Sun.COM 	iser_getinfo,		/* getinfo */
849162SPeter.Dunlap@Sun.COM 	nulldev,		/* identify */
859162SPeter.Dunlap@Sun.COM 	nulldev,		/* probe */
869162SPeter.Dunlap@Sun.COM 	iser_attach,		/* attach */
879162SPeter.Dunlap@Sun.COM 	iser_detach,		/* detach */
889162SPeter.Dunlap@Sun.COM 	nodev,			/* reset */
899162SPeter.Dunlap@Sun.COM 	&iser_cb_ops,		/* cb_ops */
909162SPeter.Dunlap@Sun.COM 	NULL,			/* bus ops */
919162SPeter.Dunlap@Sun.COM 	NULL,			/* power */
929162SPeter.Dunlap@Sun.COM 	ddi_quiesce_not_needed	/* quiesce */
939162SPeter.Dunlap@Sun.COM };
949162SPeter.Dunlap@Sun.COM 
959162SPeter.Dunlap@Sun.COM /* Module Driver Info */
969162SPeter.Dunlap@Sun.COM #define	ISER_NAME_VERSION	"iSCSI Extensions for RDMA"
979162SPeter.Dunlap@Sun.COM static struct modldrv iser_modldrv = {
989162SPeter.Dunlap@Sun.COM 	&mod_driverops,
999162SPeter.Dunlap@Sun.COM 	ISER_NAME_VERSION,
1009162SPeter.Dunlap@Sun.COM 	&iser_ops,
1019162SPeter.Dunlap@Sun.COM };
1029162SPeter.Dunlap@Sun.COM 
1039162SPeter.Dunlap@Sun.COM /* Module Linkage */
1049162SPeter.Dunlap@Sun.COM static struct modlinkage iser_modlinkage = {
1059162SPeter.Dunlap@Sun.COM 	MODREV_1,
1069162SPeter.Dunlap@Sun.COM 	&iser_modldrv,
1079162SPeter.Dunlap@Sun.COM 	NULL
1089162SPeter.Dunlap@Sun.COM };
1099162SPeter.Dunlap@Sun.COM 
1109162SPeter.Dunlap@Sun.COM /*
1119162SPeter.Dunlap@Sun.COM  * _init()
1129162SPeter.Dunlap@Sun.COM  */
1139162SPeter.Dunlap@Sun.COM int
_init(void)1149162SPeter.Dunlap@Sun.COM _init(void)
1159162SPeter.Dunlap@Sun.COM {
1169162SPeter.Dunlap@Sun.COM 	int	status;
1179162SPeter.Dunlap@Sun.COM 
1189162SPeter.Dunlap@Sun.COM 	iser_state = kmem_zalloc(sizeof (iser_state_t), KM_SLEEP);
1199162SPeter.Dunlap@Sun.COM 	status = mod_install(&iser_modlinkage);
1209162SPeter.Dunlap@Sun.COM 	if (status != DDI_SUCCESS) {
1219162SPeter.Dunlap@Sun.COM 		kmem_free(iser_state, sizeof (iser_state_t));
1229162SPeter.Dunlap@Sun.COM 	}
1239162SPeter.Dunlap@Sun.COM 
1249162SPeter.Dunlap@Sun.COM 	return (status);
1259162SPeter.Dunlap@Sun.COM }
1269162SPeter.Dunlap@Sun.COM 
1279162SPeter.Dunlap@Sun.COM /*
1289162SPeter.Dunlap@Sun.COM  * _info()
1299162SPeter.Dunlap@Sun.COM  */
1309162SPeter.Dunlap@Sun.COM int
_info(struct modinfo * modinfop)1319162SPeter.Dunlap@Sun.COM _info(struct modinfo *modinfop)
1329162SPeter.Dunlap@Sun.COM {
1339162SPeter.Dunlap@Sun.COM 	return (mod_info(&iser_modlinkage, modinfop));
1349162SPeter.Dunlap@Sun.COM }
1359162SPeter.Dunlap@Sun.COM 
1369162SPeter.Dunlap@Sun.COM /*
1379162SPeter.Dunlap@Sun.COM  * _fini()
1389162SPeter.Dunlap@Sun.COM  */
1399162SPeter.Dunlap@Sun.COM int
_fini(void)1409162SPeter.Dunlap@Sun.COM _fini(void)
1419162SPeter.Dunlap@Sun.COM {
1429162SPeter.Dunlap@Sun.COM 	int status;
1439162SPeter.Dunlap@Sun.COM 
1449162SPeter.Dunlap@Sun.COM 	status = mod_remove(&iser_modlinkage);
1459162SPeter.Dunlap@Sun.COM 	if (status != DDI_SUCCESS) {
1469162SPeter.Dunlap@Sun.COM 		return (status);
1479162SPeter.Dunlap@Sun.COM 	}
1489162SPeter.Dunlap@Sun.COM 	kmem_free(iser_state, sizeof (iser_state_t));
1499162SPeter.Dunlap@Sun.COM 
1509162SPeter.Dunlap@Sun.COM 	return (DDI_SUCCESS);
1519162SPeter.Dunlap@Sun.COM }
1529162SPeter.Dunlap@Sun.COM 
1539162SPeter.Dunlap@Sun.COM /*
1549162SPeter.Dunlap@Sun.COM  * iser_attach()
1559162SPeter.Dunlap@Sun.COM  */
1569162SPeter.Dunlap@Sun.COM static int
iser_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1579162SPeter.Dunlap@Sun.COM iser_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1589162SPeter.Dunlap@Sun.COM {
1599162SPeter.Dunlap@Sun.COM 	int		instance;
1609162SPeter.Dunlap@Sun.COM 	int		status;
1619162SPeter.Dunlap@Sun.COM 
1629162SPeter.Dunlap@Sun.COM 	switch (cmd) {
1639162SPeter.Dunlap@Sun.COM 	case DDI_ATTACH:
1649162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "iser_attach: DDI_ATTACH");
1659162SPeter.Dunlap@Sun.COM 		instance = ddi_get_instance(dip);
1669162SPeter.Dunlap@Sun.COM 
1679162SPeter.Dunlap@Sun.COM 		iser_state->is_dip = dip;
1689162SPeter.Dunlap@Sun.COM 		iser_state->is_instance = instance;
1699162SPeter.Dunlap@Sun.COM 
1709162SPeter.Dunlap@Sun.COM 		/* Initialize the open refcnt and it's lock */
1719162SPeter.Dunlap@Sun.COM 		iser_state->is_open_refcnt = 0;
1729162SPeter.Dunlap@Sun.COM 		mutex_init(&iser_state->is_refcnt_lock, NULL, MUTEX_DRIVER,
1739162SPeter.Dunlap@Sun.COM 		    NULL);
1749162SPeter.Dunlap@Sun.COM 
1759162SPeter.Dunlap@Sun.COM 		iser_taskq = ddi_taskq_create(dip, "iser_taskq",
1769162SPeter.Dunlap@Sun.COM 		    ISER_TASKQ_NTHREADS, TASKQ_DEFAULTPRI, 0);
1779162SPeter.Dunlap@Sun.COM 
1789162SPeter.Dunlap@Sun.COM 		if (iser_taskq == NULL) {
1799162SPeter.Dunlap@Sun.COM 			ISER_LOG(CE_CONT, "%s%d: failed to create taskq",
1809162SPeter.Dunlap@Sun.COM 			    "iser", instance);
1819162SPeter.Dunlap@Sun.COM 			mutex_destroy(&iser_state->is_refcnt_lock);
1829162SPeter.Dunlap@Sun.COM 			return (DDI_FAILURE);
1839162SPeter.Dunlap@Sun.COM 		}
1849162SPeter.Dunlap@Sun.COM 
1859162SPeter.Dunlap@Sun.COM 		/* initialize iSER as IB service */
1869162SPeter.Dunlap@Sun.COM 		status = iser_ib_init();
1879162SPeter.Dunlap@Sun.COM 		if (status != DDI_SUCCESS) {
1889162SPeter.Dunlap@Sun.COM 			ddi_taskq_destroy(iser_taskq);
1899162SPeter.Dunlap@Sun.COM 			mutex_destroy(&iser_state->is_refcnt_lock);
1909162SPeter.Dunlap@Sun.COM 			ISER_LOG(CE_CONT, "%s%d: failed to initialize IB",
1919162SPeter.Dunlap@Sun.COM 			    "iser", instance);
1929162SPeter.Dunlap@Sun.COM 			return (DDI_FAILURE);
1939162SPeter.Dunlap@Sun.COM 		}
1949162SPeter.Dunlap@Sun.COM 
1959162SPeter.Dunlap@Sun.COM 		status = ddi_create_minor_node(
1969162SPeter.Dunlap@Sun.COM 		    dip, ddi_get_name(dip), S_IFCHR, instance,
1979162SPeter.Dunlap@Sun.COM 		    DDI_PSEUDO, 0);
1989162SPeter.Dunlap@Sun.COM 		if (status != DDI_SUCCESS) {
1999162SPeter.Dunlap@Sun.COM 			(void) iser_ib_fini();
2009162SPeter.Dunlap@Sun.COM 			ddi_taskq_destroy(iser_taskq);
2019162SPeter.Dunlap@Sun.COM 			mutex_destroy(&iser_state->is_refcnt_lock);
2029162SPeter.Dunlap@Sun.COM 			ISER_LOG(CE_CONT, "%s%d: failed ddi_create_minor_node",
2039162SPeter.Dunlap@Sun.COM 			    "iser", instance);
2049162SPeter.Dunlap@Sun.COM 			return (DDI_FAILURE);
2059162SPeter.Dunlap@Sun.COM 		}
2069162SPeter.Dunlap@Sun.COM 
2079162SPeter.Dunlap@Sun.COM 		ddi_report_dev(dip);
2089162SPeter.Dunlap@Sun.COM 
2099162SPeter.Dunlap@Sun.COM 		return (DDI_SUCCESS);
2109162SPeter.Dunlap@Sun.COM 
2119162SPeter.Dunlap@Sun.COM 	case DDI_RESUME:
2129162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "iser_detach: DDI_RESUME unsupported");
2139162SPeter.Dunlap@Sun.COM 		return (DDI_FAILURE);
2149162SPeter.Dunlap@Sun.COM 
2159162SPeter.Dunlap@Sun.COM 	default:
2169162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "%s%d: unknown cmd in attach (0x%x)", "iser",
2179162SPeter.Dunlap@Sun.COM 		    instance, cmd);
2189162SPeter.Dunlap@Sun.COM 		return (DDI_FAILURE);
2199162SPeter.Dunlap@Sun.COM 	}
2209162SPeter.Dunlap@Sun.COM }
2219162SPeter.Dunlap@Sun.COM 
2229162SPeter.Dunlap@Sun.COM /*
2239162SPeter.Dunlap@Sun.COM  * iser_detach()
2249162SPeter.Dunlap@Sun.COM  */
2259162SPeter.Dunlap@Sun.COM static int
iser_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)2269162SPeter.Dunlap@Sun.COM iser_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
2279162SPeter.Dunlap@Sun.COM {
2289162SPeter.Dunlap@Sun.COM 	mutex_enter(&iser_state->is_refcnt_lock);
2299162SPeter.Dunlap@Sun.COM 	if (iser_state->is_open_refcnt > 0) {
2309162SPeter.Dunlap@Sun.COM 		mutex_exit(&iser_state->is_refcnt_lock);
2319162SPeter.Dunlap@Sun.COM 		return (DDI_FAILURE);
2329162SPeter.Dunlap@Sun.COM 	}
2339162SPeter.Dunlap@Sun.COM 	mutex_exit(&iser_state->is_refcnt_lock);
2349162SPeter.Dunlap@Sun.COM 	mutex_destroy(&iser_state->is_refcnt_lock);
2359162SPeter.Dunlap@Sun.COM 
2369162SPeter.Dunlap@Sun.COM 	switch (cmd) {
2379162SPeter.Dunlap@Sun.COM 	case DDI_DETACH:
2389162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "iser_detach: DDI_DETACH");
2399162SPeter.Dunlap@Sun.COM 
2409162SPeter.Dunlap@Sun.COM 		if (iser_ib_fini() != DDI_SUCCESS) {
2419162SPeter.Dunlap@Sun.COM 			ISER_LOG(CE_CONT, "iser_ib_fini failed");
2429162SPeter.Dunlap@Sun.COM 			return (DDI_FAILURE);
2439162SPeter.Dunlap@Sun.COM 		}
2449162SPeter.Dunlap@Sun.COM 
2459162SPeter.Dunlap@Sun.COM 		if (iser_taskq != NULL) {
2469162SPeter.Dunlap@Sun.COM 			ddi_taskq_destroy(iser_taskq);
2479162SPeter.Dunlap@Sun.COM 			iser_taskq = NULL;
2489162SPeter.Dunlap@Sun.COM 		}
2499162SPeter.Dunlap@Sun.COM 		ddi_remove_minor_node(dip, NULL);
2509162SPeter.Dunlap@Sun.COM 
2519162SPeter.Dunlap@Sun.COM 		return (DDI_SUCCESS);
2529162SPeter.Dunlap@Sun.COM 
2539162SPeter.Dunlap@Sun.COM 	case DDI_SUSPEND:
2549162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "iser_detach: DDI_SUSPEND unsupported");
2559162SPeter.Dunlap@Sun.COM 		return (DDI_FAILURE);
2569162SPeter.Dunlap@Sun.COM 
2579162SPeter.Dunlap@Sun.COM 	default:
2589162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "iser: unknown cmd in detach (0x%x)", cmd);
2599162SPeter.Dunlap@Sun.COM 		return (DDI_FAILURE);
2609162SPeter.Dunlap@Sun.COM 	}
2619162SPeter.Dunlap@Sun.COM }
2629162SPeter.Dunlap@Sun.COM 
2639162SPeter.Dunlap@Sun.COM /*
2649162SPeter.Dunlap@Sun.COM  * iser_getinfo()
2659162SPeter.Dunlap@Sun.COM  */
2669162SPeter.Dunlap@Sun.COM /* ARGSUSED */
2679162SPeter.Dunlap@Sun.COM static int
iser_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)2689162SPeter.Dunlap@Sun.COM iser_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
2699162SPeter.Dunlap@Sun.COM {
2709162SPeter.Dunlap@Sun.COM 	switch (cmd) {
2719162SPeter.Dunlap@Sun.COM 	case DDI_INFO_DEVT2DEVINFO:
2729162SPeter.Dunlap@Sun.COM 		*result = (void *)iser_state->is_dip;
2739162SPeter.Dunlap@Sun.COM 		return (DDI_SUCCESS);
2749162SPeter.Dunlap@Sun.COM 
2759162SPeter.Dunlap@Sun.COM 	case DDI_INFO_DEVT2INSTANCE:
2769162SPeter.Dunlap@Sun.COM 		*result = NULL;
2779162SPeter.Dunlap@Sun.COM 		return (DDI_SUCCESS);
2789162SPeter.Dunlap@Sun.COM 
2799162SPeter.Dunlap@Sun.COM 	default:
2809162SPeter.Dunlap@Sun.COM 		return (DDI_FAILURE);
2819162SPeter.Dunlap@Sun.COM 	}
2829162SPeter.Dunlap@Sun.COM 
2839162SPeter.Dunlap@Sun.COM }
2849162SPeter.Dunlap@Sun.COM 
2859162SPeter.Dunlap@Sun.COM /*
2869162SPeter.Dunlap@Sun.COM  * iser_open()
2879162SPeter.Dunlap@Sun.COM  */
2889162SPeter.Dunlap@Sun.COM /* ARGSUSED */
2899162SPeter.Dunlap@Sun.COM static int
iser_open(dev_t * devp,int flag,int otyp,cred_t * credp)2909162SPeter.Dunlap@Sun.COM iser_open(dev_t *devp, int flag, int otyp, cred_t *credp)
2919162SPeter.Dunlap@Sun.COM {
2929162SPeter.Dunlap@Sun.COM 	minor_t		instance;
2939162SPeter.Dunlap@Sun.COM 	int		status;
2949162SPeter.Dunlap@Sun.COM 
2959162SPeter.Dunlap@Sun.COM 	instance = getminor(*devp);
2969162SPeter.Dunlap@Sun.COM 
2979162SPeter.Dunlap@Sun.COM 	/* Register the transport with IDM */
2989162SPeter.Dunlap@Sun.COM 	status = iser_idm_register();
2999162SPeter.Dunlap@Sun.COM 	if (status != DDI_SUCCESS) {
3009162SPeter.Dunlap@Sun.COM 		ISER_LOG(CE_CONT, "%s%d: failed to register with IDM",
3019162SPeter.Dunlap@Sun.COM 		    "iser", instance);
3029162SPeter.Dunlap@Sun.COM 		return (ENXIO);
3039162SPeter.Dunlap@Sun.COM 	}
3049162SPeter.Dunlap@Sun.COM 
3059162SPeter.Dunlap@Sun.COM 	/* Increment our open refcnt */
3069162SPeter.Dunlap@Sun.COM 	mutex_enter(&iser_state->is_refcnt_lock);
3079162SPeter.Dunlap@Sun.COM 	iser_state->is_open_refcnt++;
3089162SPeter.Dunlap@Sun.COM 	mutex_exit(&iser_state->is_refcnt_lock);
3099162SPeter.Dunlap@Sun.COM 
3109162SPeter.Dunlap@Sun.COM 	return (DDI_SUCCESS);
3119162SPeter.Dunlap@Sun.COM }
3129162SPeter.Dunlap@Sun.COM 
3139162SPeter.Dunlap@Sun.COM /*
3149162SPeter.Dunlap@Sun.COM  * iser_close()
3159162SPeter.Dunlap@Sun.COM  */
3169162SPeter.Dunlap@Sun.COM /* ARGSUSED */
3179162SPeter.Dunlap@Sun.COM static int
iser_close(dev_t devp,int flag,int otyp,cred_t * credp)3189162SPeter.Dunlap@Sun.COM iser_close(dev_t devp, int flag, int otyp, cred_t *credp)
3199162SPeter.Dunlap@Sun.COM {
3209162SPeter.Dunlap@Sun.COM 	ASSERT(iser_state->is_open_refcnt != 0);
3219162SPeter.Dunlap@Sun.COM 
3229162SPeter.Dunlap@Sun.COM 	mutex_enter(&iser_state->is_refcnt_lock);
3239162SPeter.Dunlap@Sun.COM 	iser_state->is_open_refcnt--;
3249162SPeter.Dunlap@Sun.COM 	mutex_exit(&iser_state->is_refcnt_lock);
3259162SPeter.Dunlap@Sun.COM 
3269162SPeter.Dunlap@Sun.COM 	return (DDI_SUCCESS);
3279162SPeter.Dunlap@Sun.COM }
3289162SPeter.Dunlap@Sun.COM 
3299162SPeter.Dunlap@Sun.COM iser_status_t
iser_register_service(idm_svc_t * idm_svc)3309162SPeter.Dunlap@Sun.COM iser_register_service(idm_svc_t *idm_svc)
3319162SPeter.Dunlap@Sun.COM {
3329162SPeter.Dunlap@Sun.COM 
3339162SPeter.Dunlap@Sun.COM 	return (iser_ib_register_service(idm_svc));
3349162SPeter.Dunlap@Sun.COM }
3359162SPeter.Dunlap@Sun.COM 
3369162SPeter.Dunlap@Sun.COM iser_status_t
iser_bind_service(idm_svc_t * idm_svc)3379162SPeter.Dunlap@Sun.COM iser_bind_service(idm_svc_t *idm_svc)
3389162SPeter.Dunlap@Sun.COM {
3399162SPeter.Dunlap@Sun.COM 
3409162SPeter.Dunlap@Sun.COM 	return (iser_ib_bind_service(idm_svc));
3419162SPeter.Dunlap@Sun.COM }
3429162SPeter.Dunlap@Sun.COM 
3439162SPeter.Dunlap@Sun.COM void
iser_unbind_service(idm_svc_t * idm_svc)3449162SPeter.Dunlap@Sun.COM iser_unbind_service(idm_svc_t *idm_svc)
3459162SPeter.Dunlap@Sun.COM {
3469162SPeter.Dunlap@Sun.COM 
3479162SPeter.Dunlap@Sun.COM 	iser_ib_unbind_service(idm_svc);
3489162SPeter.Dunlap@Sun.COM }
3499162SPeter.Dunlap@Sun.COM 
3509162SPeter.Dunlap@Sun.COM void
iser_deregister_service(idm_svc_t * idm_svc)3519162SPeter.Dunlap@Sun.COM iser_deregister_service(idm_svc_t *idm_svc)
3529162SPeter.Dunlap@Sun.COM {
3539162SPeter.Dunlap@Sun.COM 
3549162SPeter.Dunlap@Sun.COM 	iser_ib_deregister_service(idm_svc);
3559162SPeter.Dunlap@Sun.COM }
3569162SPeter.Dunlap@Sun.COM 
3579162SPeter.Dunlap@Sun.COM /*
3589162SPeter.Dunlap@Sun.COM  * iser_path_exists
3599162SPeter.Dunlap@Sun.COM  * This function takes in a pair of endpoints and determines if an iSER path
3609162SPeter.Dunlap@Sun.COM  * exists between the two. The actual path information (required for creating
3619162SPeter.Dunlap@Sun.COM  * a RC channel) is not returned, instead a boolean value indicating if a path
3629162SPeter.Dunlap@Sun.COM  * exists is returned.
3639162SPeter.Dunlap@Sun.COM  *
3649162SPeter.Dunlap@Sun.COM  * To use an implicit source, a value of NULL is allowed for laddr.
3659162SPeter.Dunlap@Sun.COM  */
3669162SPeter.Dunlap@Sun.COM boolean_t
iser_path_exists(idm_sockaddr_t * laddr,idm_sockaddr_t * raddr)3679162SPeter.Dunlap@Sun.COM iser_path_exists(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr)
3689162SPeter.Dunlap@Sun.COM {
3699162SPeter.Dunlap@Sun.COM 
3709162SPeter.Dunlap@Sun.COM 	ibt_ip_addr_t		remote_ip, local_ip;
3719162SPeter.Dunlap@Sun.COM 	ibt_path_info_t		path;
3729162SPeter.Dunlap@Sun.COM 	int			status;
3739162SPeter.Dunlap@Sun.COM 
3749162SPeter.Dunlap@Sun.COM 	iser_ib_conv_sockaddr2ibtaddr(raddr, &remote_ip);
3759162SPeter.Dunlap@Sun.COM 	iser_ib_conv_sockaddr2ibtaddr(laddr, &local_ip);
3769162SPeter.Dunlap@Sun.COM 
3779162SPeter.Dunlap@Sun.COM 	status = iser_ib_get_paths(&local_ip, &remote_ip, &path, NULL);
3789162SPeter.Dunlap@Sun.COM 
3799162SPeter.Dunlap@Sun.COM 	return ((status == IBT_SUCCESS) ? B_TRUE : B_FALSE);
3809162SPeter.Dunlap@Sun.COM }
3819162SPeter.Dunlap@Sun.COM 
3829162SPeter.Dunlap@Sun.COM /*
3839162SPeter.Dunlap@Sun.COM  * iser_channel_alloc
3849162SPeter.Dunlap@Sun.COM  * This function allocates a reliable communication channel between the
3859162SPeter.Dunlap@Sun.COM  * given endpoints.
3869162SPeter.Dunlap@Sun.COM  */
3879162SPeter.Dunlap@Sun.COM iser_chan_t *
iser_channel_alloc(idm_sockaddr_t * laddr,idm_sockaddr_t * raddr)3889162SPeter.Dunlap@Sun.COM iser_channel_alloc(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr)
3899162SPeter.Dunlap@Sun.COM {
3909162SPeter.Dunlap@Sun.COM 	ibt_ip_addr_t		remote_ip, local_ip;
3919162SPeter.Dunlap@Sun.COM 
3929162SPeter.Dunlap@Sun.COM 	iser_ib_conv_sockaddr2ibtaddr(raddr, &remote_ip);
3939162SPeter.Dunlap@Sun.COM 	iser_ib_conv_sockaddr2ibtaddr(laddr, &local_ip);
3949162SPeter.Dunlap@Sun.COM 
395*10322SPriya.Krishnan@Sun.COM 	return (iser_ib_alloc_channel_pathlookup(&local_ip, &remote_ip));
3969162SPeter.Dunlap@Sun.COM }
3979162SPeter.Dunlap@Sun.COM 
3989162SPeter.Dunlap@Sun.COM /*
3999162SPeter.Dunlap@Sun.COM  * iser_channel_open
4009162SPeter.Dunlap@Sun.COM  * This function opens the already allocated communication channel between the
4019162SPeter.Dunlap@Sun.COM  * two endpoints.
4029162SPeter.Dunlap@Sun.COM  */
4039162SPeter.Dunlap@Sun.COM iser_status_t
iser_channel_open(iser_chan_t * chan)4049162SPeter.Dunlap@Sun.COM iser_channel_open(iser_chan_t *chan)
4059162SPeter.Dunlap@Sun.COM {
4069162SPeter.Dunlap@Sun.COM 	return (iser_ib_open_rc_channel(chan));
4079162SPeter.Dunlap@Sun.COM }
4089162SPeter.Dunlap@Sun.COM 
4099162SPeter.Dunlap@Sun.COM /*
4109162SPeter.Dunlap@Sun.COM  * iser_channel_close
4119162SPeter.Dunlap@Sun.COM  * This function closes the already opened communication channel between the
4129162SPeter.Dunlap@Sun.COM  * two endpoints.
4139162SPeter.Dunlap@Sun.COM  */
4149162SPeter.Dunlap@Sun.COM void
iser_channel_close(iser_chan_t * chan)4159162SPeter.Dunlap@Sun.COM iser_channel_close(iser_chan_t *chan)
4169162SPeter.Dunlap@Sun.COM {
4179162SPeter.Dunlap@Sun.COM 	iser_ib_close_rc_channel(chan);
4189162SPeter.Dunlap@Sun.COM }
4199162SPeter.Dunlap@Sun.COM 
4209162SPeter.Dunlap@Sun.COM /*
4219162SPeter.Dunlap@Sun.COM  * iser_channel_free
4229162SPeter.Dunlap@Sun.COM  * This function frees the channel between the given endpoints
4239162SPeter.Dunlap@Sun.COM  */
4249162SPeter.Dunlap@Sun.COM void
iser_channel_free(iser_chan_t * chan)4259162SPeter.Dunlap@Sun.COM iser_channel_free(iser_chan_t *chan)
4269162SPeter.Dunlap@Sun.COM {
4279162SPeter.Dunlap@Sun.COM 	iser_ib_free_rc_channel(chan);
4289162SPeter.Dunlap@Sun.COM }
4299162SPeter.Dunlap@Sun.COM 
4309162SPeter.Dunlap@Sun.COM /* ARGSUSED */
4319162SPeter.Dunlap@Sun.COM static int
iser_ioctl(dev_t devp,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)4329162SPeter.Dunlap@Sun.COM iser_ioctl(dev_t devp, int cmd, intptr_t arg, int mode, cred_t *credp,
4339162SPeter.Dunlap@Sun.COM     int *rvalp)
4349162SPeter.Dunlap@Sun.COM {
4359162SPeter.Dunlap@Sun.COM 	return (DDI_SUCCESS);
4369162SPeter.Dunlap@Sun.COM }
437