130e7468fSPeter Dunlap /*
230e7468fSPeter Dunlap  * CDDL HEADER START
330e7468fSPeter Dunlap  *
430e7468fSPeter Dunlap  * The contents of this file are subject to the terms of the
530e7468fSPeter Dunlap  * Common Development and Distribution License (the "License").
630e7468fSPeter Dunlap  * You may not use this file except in compliance with the License.
730e7468fSPeter Dunlap  *
830e7468fSPeter Dunlap  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
930e7468fSPeter Dunlap  * or http://www.opensolaris.org/os/licensing.
1030e7468fSPeter Dunlap  * See the License for the specific language governing permissions
1130e7468fSPeter Dunlap  * and limitations under the License.
1230e7468fSPeter Dunlap  *
1330e7468fSPeter Dunlap  * When distributing Covered Code, include this CDDL HEADER in each
1430e7468fSPeter Dunlap  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1530e7468fSPeter Dunlap  * If applicable, add the following below this CDDL HEADER, with the
1630e7468fSPeter Dunlap  * fields enclosed by brackets "[]" replaced with your own identifying
1730e7468fSPeter Dunlap  * information: Portions Copyright [yyyy] [name of copyright owner]
1830e7468fSPeter Dunlap  *
1930e7468fSPeter Dunlap  * CDDL HEADER END
2030e7468fSPeter Dunlap  */
2130e7468fSPeter Dunlap /*
2230e7468fSPeter Dunlap  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2330e7468fSPeter Dunlap  * Use is subject to license terms.
2430e7468fSPeter Dunlap  */
2530e7468fSPeter Dunlap 
2630e7468fSPeter Dunlap #include <sys/types.h>
2730e7468fSPeter Dunlap #include <sys/stat.h>
2830e7468fSPeter Dunlap #include <sys/conf.h>
2930e7468fSPeter Dunlap #include <sys/ddi.h>
3030e7468fSPeter Dunlap #include <sys/sunddi.h>
3130e7468fSPeter Dunlap #include <sys/modctl.h>
3230e7468fSPeter Dunlap #include <sys/socket.h>
3330e7468fSPeter Dunlap #include <netinet/in.h>
3430e7468fSPeter Dunlap 
3530e7468fSPeter Dunlap #include <sys/ib/clients/iser/iser.h>
3630e7468fSPeter Dunlap 
3730e7468fSPeter Dunlap /*
3830e7468fSPeter Dunlap  * iser.c
3930e7468fSPeter Dunlap  *    DDI and core routines for Solaris iSER implementation.
4030e7468fSPeter Dunlap  */
4130e7468fSPeter Dunlap 
4230e7468fSPeter Dunlap iser_state_t	*iser_state = NULL;	/* global state */
4330e7468fSPeter Dunlap ddi_taskq_t	*iser_taskq = NULL;	/* global taskq */
4430e7468fSPeter Dunlap 
4530e7468fSPeter Dunlap /* set B_TRUE for console logging */
4630e7468fSPeter Dunlap boolean_t iser_logging = B_FALSE;
4730e7468fSPeter Dunlap 
4830e7468fSPeter Dunlap /* Driver functions */
4930e7468fSPeter Dunlap static int iser_attach(dev_info_t *, ddi_attach_cmd_t);
5030e7468fSPeter Dunlap static int iser_detach(dev_info_t *, ddi_detach_cmd_t);
5130e7468fSPeter Dunlap static int iser_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
5230e7468fSPeter Dunlap static int iser_open(dev_t *, int, int, cred_t *);
5330e7468fSPeter Dunlap static int iser_close(dev_t, int, int, cred_t *);
5430e7468fSPeter Dunlap static int iser_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
5530e7468fSPeter Dunlap /* static int iser_close(dev_t, int, int, cred_t *); */
5630e7468fSPeter Dunlap 
5730e7468fSPeter Dunlap /* Char/Block operations */
5830e7468fSPeter Dunlap static struct cb_ops	iser_cb_ops = {
5930e7468fSPeter Dunlap 	iser_open,		/* open */
6030e7468fSPeter Dunlap 	iser_close,		/* close */
6130e7468fSPeter Dunlap 	nodev,			/* strategy */
6230e7468fSPeter Dunlap 	nodev,			/* print */
6330e7468fSPeter Dunlap 	nodev,			/* dump */
6430e7468fSPeter Dunlap 	nodev,			/* read */
6530e7468fSPeter Dunlap 	nodev,			/* write */
6630e7468fSPeter Dunlap 	iser_ioctl,		/* ioctl */
6730e7468fSPeter Dunlap 	nodev,			/* devmap */
6830e7468fSPeter Dunlap 	nodev,			/* mmap */
6930e7468fSPeter Dunlap 	nodev,			/* segmap */
7030e7468fSPeter Dunlap 	nochpoll,		/* poll */
7130e7468fSPeter Dunlap 	ddi_prop_op,		/* prop_op */
7230e7468fSPeter Dunlap 	NULL,			/* stream */
7330e7468fSPeter Dunlap 	D_MP,			/* cb_flag */
7430e7468fSPeter Dunlap 	CB_REV,			/* rev */
7530e7468fSPeter Dunlap 	nodev,			/* int (*cb_aread)() */
7630e7468fSPeter Dunlap 	nodev,			/* int (*cb_awrite)() */
7730e7468fSPeter Dunlap };
7830e7468fSPeter Dunlap 
7930e7468fSPeter Dunlap /* Device operations */
8030e7468fSPeter Dunlap static struct dev_ops iser_ops = {
8130e7468fSPeter Dunlap 	DEVO_REV,		/* devo_rev, */
8230e7468fSPeter Dunlap 	0,			/* refcnt  */
8330e7468fSPeter Dunlap 	iser_getinfo,		/* getinfo */
8430e7468fSPeter Dunlap 	nulldev,		/* identify */
8530e7468fSPeter Dunlap 	nulldev,		/* probe */
8630e7468fSPeter Dunlap 	iser_attach,		/* attach */
8730e7468fSPeter Dunlap 	iser_detach,		/* detach */
8830e7468fSPeter Dunlap 	nodev,			/* reset */
8930e7468fSPeter Dunlap 	&iser_cb_ops,		/* cb_ops */
9030e7468fSPeter Dunlap 	NULL,			/* bus ops */
9130e7468fSPeter Dunlap 	NULL,			/* power */
9230e7468fSPeter Dunlap 	ddi_quiesce_not_needed	/* quiesce */
9330e7468fSPeter Dunlap };
9430e7468fSPeter Dunlap 
9530e7468fSPeter Dunlap /* Module Driver Info */
9630e7468fSPeter Dunlap #define	ISER_NAME_VERSION	"iSCSI Extensions for RDMA"
9730e7468fSPeter Dunlap static struct modldrv iser_modldrv = {
9830e7468fSPeter Dunlap 	&mod_driverops,
9930e7468fSPeter Dunlap 	ISER_NAME_VERSION,
10030e7468fSPeter Dunlap 	&iser_ops,
10130e7468fSPeter Dunlap };
10230e7468fSPeter Dunlap 
10330e7468fSPeter Dunlap /* Module Linkage */
10430e7468fSPeter Dunlap static struct modlinkage iser_modlinkage = {
10530e7468fSPeter Dunlap 	MODREV_1,
10630e7468fSPeter Dunlap 	&iser_modldrv,
10730e7468fSPeter Dunlap 	NULL
10830e7468fSPeter Dunlap };
10930e7468fSPeter Dunlap 
11030e7468fSPeter Dunlap /*
11130e7468fSPeter Dunlap  * _init()
11230e7468fSPeter Dunlap  */
11330e7468fSPeter Dunlap int
_init(void)11430e7468fSPeter Dunlap _init(void)
11530e7468fSPeter Dunlap {
11630e7468fSPeter Dunlap 	int	status;
11730e7468fSPeter Dunlap 
11830e7468fSPeter Dunlap 	iser_state = kmem_zalloc(sizeof (iser_state_t), KM_SLEEP);
11930e7468fSPeter Dunlap 	status = mod_install(&iser_modlinkage);
12030e7468fSPeter Dunlap 	if (status != DDI_SUCCESS) {
12130e7468fSPeter Dunlap 		kmem_free(iser_state, sizeof (iser_state_t));
12230e7468fSPeter Dunlap 	}
12330e7468fSPeter Dunlap 
12430e7468fSPeter Dunlap 	return (status);
12530e7468fSPeter Dunlap }
12630e7468fSPeter Dunlap 
12730e7468fSPeter Dunlap /*
12830e7468fSPeter Dunlap  * _info()
12930e7468fSPeter Dunlap  */
13030e7468fSPeter Dunlap int
_info(struct modinfo * modinfop)13130e7468fSPeter Dunlap _info(struct modinfo *modinfop)
13230e7468fSPeter Dunlap {
13330e7468fSPeter Dunlap 	return (mod_info(&iser_modlinkage, modinfop));
13430e7468fSPeter Dunlap }
13530e7468fSPeter Dunlap 
13630e7468fSPeter Dunlap /*
13730e7468fSPeter Dunlap  * _fini()
13830e7468fSPeter Dunlap  */
13930e7468fSPeter Dunlap int
_fini(void)14030e7468fSPeter Dunlap _fini(void)
14130e7468fSPeter Dunlap {
14230e7468fSPeter Dunlap 	int status;
14330e7468fSPeter Dunlap 
14430e7468fSPeter Dunlap 	status = mod_remove(&iser_modlinkage);
14530e7468fSPeter Dunlap 	if (status != DDI_SUCCESS) {
14630e7468fSPeter Dunlap 		return (status);
14730e7468fSPeter Dunlap 	}
14830e7468fSPeter Dunlap 	kmem_free(iser_state, sizeof (iser_state_t));
14930e7468fSPeter Dunlap 
15030e7468fSPeter Dunlap 	return (DDI_SUCCESS);
15130e7468fSPeter Dunlap }
15230e7468fSPeter Dunlap 
15330e7468fSPeter Dunlap /*
15430e7468fSPeter Dunlap  * iser_attach()
15530e7468fSPeter Dunlap  */
15630e7468fSPeter Dunlap static int
iser_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)15730e7468fSPeter Dunlap iser_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
15830e7468fSPeter Dunlap {
15930e7468fSPeter Dunlap 	int		instance;
16030e7468fSPeter Dunlap 	int		status;
16130e7468fSPeter Dunlap 
16230e7468fSPeter Dunlap 	switch (cmd) {
16330e7468fSPeter Dunlap 	case DDI_ATTACH:
16430e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "iser_attach: DDI_ATTACH");
16530e7468fSPeter Dunlap 		instance = ddi_get_instance(dip);
16630e7468fSPeter Dunlap 
16730e7468fSPeter Dunlap 		iser_state->is_dip = dip;
16830e7468fSPeter Dunlap 		iser_state->is_instance = instance;
16930e7468fSPeter Dunlap 
17030e7468fSPeter Dunlap 		/* Initialize the open refcnt and it's lock */
17130e7468fSPeter Dunlap 		iser_state->is_open_refcnt = 0;
17230e7468fSPeter Dunlap 		mutex_init(&iser_state->is_refcnt_lock, NULL, MUTEX_DRIVER,
17330e7468fSPeter Dunlap 		    NULL);
17430e7468fSPeter Dunlap 
17530e7468fSPeter Dunlap 		iser_taskq = ddi_taskq_create(dip, "iser_taskq",
17630e7468fSPeter Dunlap 		    ISER_TASKQ_NTHREADS, TASKQ_DEFAULTPRI, 0);
17730e7468fSPeter Dunlap 
17830e7468fSPeter Dunlap 		if (iser_taskq == NULL) {
17930e7468fSPeter Dunlap 			ISER_LOG(CE_CONT, "%s%d: failed to create taskq",
18030e7468fSPeter Dunlap 			    "iser", instance);
18130e7468fSPeter Dunlap 			mutex_destroy(&iser_state->is_refcnt_lock);
18230e7468fSPeter Dunlap 			return (DDI_FAILURE);
18330e7468fSPeter Dunlap 		}
18430e7468fSPeter Dunlap 
18530e7468fSPeter Dunlap 		/* initialize iSER as IB service */
18630e7468fSPeter Dunlap 		status = iser_ib_init();
18730e7468fSPeter Dunlap 		if (status != DDI_SUCCESS) {
18830e7468fSPeter Dunlap 			ddi_taskq_destroy(iser_taskq);
18930e7468fSPeter Dunlap 			mutex_destroy(&iser_state->is_refcnt_lock);
19030e7468fSPeter Dunlap 			ISER_LOG(CE_CONT, "%s%d: failed to initialize IB",
19130e7468fSPeter Dunlap 			    "iser", instance);
19230e7468fSPeter Dunlap 			return (DDI_FAILURE);
19330e7468fSPeter Dunlap 		}
19430e7468fSPeter Dunlap 
19530e7468fSPeter Dunlap 		status = ddi_create_minor_node(
19630e7468fSPeter Dunlap 		    dip, ddi_get_name(dip), S_IFCHR, instance,
19730e7468fSPeter Dunlap 		    DDI_PSEUDO, 0);
19830e7468fSPeter Dunlap 		if (status != DDI_SUCCESS) {
19930e7468fSPeter Dunlap 			(void) iser_ib_fini();
20030e7468fSPeter Dunlap 			ddi_taskq_destroy(iser_taskq);
20130e7468fSPeter Dunlap 			mutex_destroy(&iser_state->is_refcnt_lock);
20230e7468fSPeter Dunlap 			ISER_LOG(CE_CONT, "%s%d: failed ddi_create_minor_node",
20330e7468fSPeter Dunlap 			    "iser", instance);
20430e7468fSPeter Dunlap 			return (DDI_FAILURE);
20530e7468fSPeter Dunlap 		}
20630e7468fSPeter Dunlap 
20730e7468fSPeter Dunlap 		ddi_report_dev(dip);
20830e7468fSPeter Dunlap 
20930e7468fSPeter Dunlap 		return (DDI_SUCCESS);
21030e7468fSPeter Dunlap 
21130e7468fSPeter Dunlap 	case DDI_RESUME:
21230e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "iser_detach: DDI_RESUME unsupported");
21330e7468fSPeter Dunlap 		return (DDI_FAILURE);
21430e7468fSPeter Dunlap 
21530e7468fSPeter Dunlap 	default:
21630e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "%s%d: unknown cmd in attach (0x%x)", "iser",
21730e7468fSPeter Dunlap 		    instance, cmd);
21830e7468fSPeter Dunlap 		return (DDI_FAILURE);
21930e7468fSPeter Dunlap 	}
22030e7468fSPeter Dunlap }
22130e7468fSPeter Dunlap 
22230e7468fSPeter Dunlap /*
22330e7468fSPeter Dunlap  * iser_detach()
22430e7468fSPeter Dunlap  */
22530e7468fSPeter Dunlap static int
iser_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)22630e7468fSPeter Dunlap iser_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
22730e7468fSPeter Dunlap {
22830e7468fSPeter Dunlap 	mutex_enter(&iser_state->is_refcnt_lock);
22930e7468fSPeter Dunlap 	if (iser_state->is_open_refcnt > 0) {
23030e7468fSPeter Dunlap 		mutex_exit(&iser_state->is_refcnt_lock);
23130e7468fSPeter Dunlap 		return (DDI_FAILURE);
23230e7468fSPeter Dunlap 	}
23330e7468fSPeter Dunlap 	mutex_exit(&iser_state->is_refcnt_lock);
23430e7468fSPeter Dunlap 	mutex_destroy(&iser_state->is_refcnt_lock);
23530e7468fSPeter Dunlap 
23630e7468fSPeter Dunlap 	switch (cmd) {
23730e7468fSPeter Dunlap 	case DDI_DETACH:
23830e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "iser_detach: DDI_DETACH");
23930e7468fSPeter Dunlap 
24030e7468fSPeter Dunlap 		if (iser_ib_fini() != DDI_SUCCESS) {
24130e7468fSPeter Dunlap 			ISER_LOG(CE_CONT, "iser_ib_fini failed");
24230e7468fSPeter Dunlap 			return (DDI_FAILURE);
24330e7468fSPeter Dunlap 		}
24430e7468fSPeter Dunlap 
24530e7468fSPeter Dunlap 		if (iser_taskq != NULL) {
24630e7468fSPeter Dunlap 			ddi_taskq_destroy(iser_taskq);
24730e7468fSPeter Dunlap 			iser_taskq = NULL;
24830e7468fSPeter Dunlap 		}
24930e7468fSPeter Dunlap 		ddi_remove_minor_node(dip, NULL);
25030e7468fSPeter Dunlap 
25130e7468fSPeter Dunlap 		return (DDI_SUCCESS);
25230e7468fSPeter Dunlap 
25330e7468fSPeter Dunlap 	case DDI_SUSPEND:
25430e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "iser_detach: DDI_SUSPEND unsupported");
25530e7468fSPeter Dunlap 		return (DDI_FAILURE);
25630e7468fSPeter Dunlap 
25730e7468fSPeter Dunlap 	default:
25830e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "iser: unknown cmd in detach (0x%x)", cmd);
25930e7468fSPeter Dunlap 		return (DDI_FAILURE);
26030e7468fSPeter Dunlap 	}
26130e7468fSPeter Dunlap }
26230e7468fSPeter Dunlap 
26330e7468fSPeter Dunlap /*
26430e7468fSPeter Dunlap  * iser_getinfo()
26530e7468fSPeter Dunlap  */
26630e7468fSPeter Dunlap /* ARGSUSED */
26730e7468fSPeter Dunlap static int
iser_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)26830e7468fSPeter Dunlap iser_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
26930e7468fSPeter Dunlap {
27030e7468fSPeter Dunlap 	switch (cmd) {
27130e7468fSPeter Dunlap 	case DDI_INFO_DEVT2DEVINFO:
27230e7468fSPeter Dunlap 		*result = (void *)iser_state->is_dip;
27330e7468fSPeter Dunlap 		return (DDI_SUCCESS);
27430e7468fSPeter Dunlap 
27530e7468fSPeter Dunlap 	case DDI_INFO_DEVT2INSTANCE:
27630e7468fSPeter Dunlap 		*result = NULL;
27730e7468fSPeter Dunlap 		return (DDI_SUCCESS);
27830e7468fSPeter Dunlap 
27930e7468fSPeter Dunlap 	default:
28030e7468fSPeter Dunlap 		return (DDI_FAILURE);
28130e7468fSPeter Dunlap 	}
28230e7468fSPeter Dunlap 
28330e7468fSPeter Dunlap }
28430e7468fSPeter Dunlap 
28530e7468fSPeter Dunlap /*
28630e7468fSPeter Dunlap  * iser_open()
28730e7468fSPeter Dunlap  */
28830e7468fSPeter Dunlap /* ARGSUSED */
28930e7468fSPeter Dunlap static int
iser_open(dev_t * devp,int flag,int otyp,cred_t * credp)29030e7468fSPeter Dunlap iser_open(dev_t *devp, int flag, int otyp, cred_t *credp)
29130e7468fSPeter Dunlap {
29230e7468fSPeter Dunlap 	minor_t		instance;
29330e7468fSPeter Dunlap 	int		status;
29430e7468fSPeter Dunlap 
29530e7468fSPeter Dunlap 	instance = getminor(*devp);
29630e7468fSPeter Dunlap 
29730e7468fSPeter Dunlap 	/* Register the transport with IDM */
29830e7468fSPeter Dunlap 	status = iser_idm_register();
29930e7468fSPeter Dunlap 	if (status != DDI_SUCCESS) {
30030e7468fSPeter Dunlap 		ISER_LOG(CE_CONT, "%s%d: failed to register with IDM",
30130e7468fSPeter Dunlap 		    "iser", instance);
30230e7468fSPeter Dunlap 		return (ENXIO);
30330e7468fSPeter Dunlap 	}
30430e7468fSPeter Dunlap 
30530e7468fSPeter Dunlap 	/* Increment our open refcnt */
30630e7468fSPeter Dunlap 	mutex_enter(&iser_state->is_refcnt_lock);
30730e7468fSPeter Dunlap 	iser_state->is_open_refcnt++;
30830e7468fSPeter Dunlap 	mutex_exit(&iser_state->is_refcnt_lock);
30930e7468fSPeter Dunlap 
31030e7468fSPeter Dunlap 	return (DDI_SUCCESS);
31130e7468fSPeter Dunlap }
31230e7468fSPeter Dunlap 
31330e7468fSPeter Dunlap /*
31430e7468fSPeter Dunlap  * iser_close()
31530e7468fSPeter Dunlap  */
31630e7468fSPeter Dunlap /* ARGSUSED */
31730e7468fSPeter Dunlap static int
iser_close(dev_t devp,int flag,int otyp,cred_t * credp)31830e7468fSPeter Dunlap iser_close(dev_t devp, int flag, int otyp, cred_t *credp)
31930e7468fSPeter Dunlap {
32030e7468fSPeter Dunlap 	ASSERT(iser_state->is_open_refcnt != 0);
32130e7468fSPeter Dunlap 
32230e7468fSPeter Dunlap 	mutex_enter(&iser_state->is_refcnt_lock);
32330e7468fSPeter Dunlap 	iser_state->is_open_refcnt--;
32430e7468fSPeter Dunlap 	mutex_exit(&iser_state->is_refcnt_lock);
32530e7468fSPeter Dunlap 
32630e7468fSPeter Dunlap 	return (DDI_SUCCESS);
32730e7468fSPeter Dunlap }
32830e7468fSPeter Dunlap 
32930e7468fSPeter Dunlap iser_status_t
iser_register_service(idm_svc_t * idm_svc)33030e7468fSPeter Dunlap iser_register_service(idm_svc_t *idm_svc)
33130e7468fSPeter Dunlap {
33230e7468fSPeter Dunlap 
33330e7468fSPeter Dunlap 	return (iser_ib_register_service(idm_svc));
33430e7468fSPeter Dunlap }
33530e7468fSPeter Dunlap 
33630e7468fSPeter Dunlap iser_status_t
iser_bind_service(idm_svc_t * idm_svc)33730e7468fSPeter Dunlap iser_bind_service(idm_svc_t *idm_svc)
33830e7468fSPeter Dunlap {
33930e7468fSPeter Dunlap 
34030e7468fSPeter Dunlap 	return (iser_ib_bind_service(idm_svc));
34130e7468fSPeter Dunlap }
34230e7468fSPeter Dunlap 
34330e7468fSPeter Dunlap void
iser_unbind_service(idm_svc_t * idm_svc)34430e7468fSPeter Dunlap iser_unbind_service(idm_svc_t *idm_svc)
34530e7468fSPeter Dunlap {
34630e7468fSPeter Dunlap 
34730e7468fSPeter Dunlap 	iser_ib_unbind_service(idm_svc);
34830e7468fSPeter Dunlap }
34930e7468fSPeter Dunlap 
35030e7468fSPeter Dunlap void
iser_deregister_service(idm_svc_t * idm_svc)35130e7468fSPeter Dunlap iser_deregister_service(idm_svc_t *idm_svc)
35230e7468fSPeter Dunlap {
35330e7468fSPeter Dunlap 
35430e7468fSPeter Dunlap 	iser_ib_deregister_service(idm_svc);
35530e7468fSPeter Dunlap }
35630e7468fSPeter Dunlap 
35730e7468fSPeter Dunlap /*
35830e7468fSPeter Dunlap  * iser_path_exists
35930e7468fSPeter Dunlap  * This function takes in a pair of endpoints and determines if an iSER path
36030e7468fSPeter Dunlap  * exists between the two. The actual path information (required for creating
36130e7468fSPeter Dunlap  * a RC channel) is not returned, instead a boolean value indicating if a path
36230e7468fSPeter Dunlap  * exists is returned.
36330e7468fSPeter Dunlap  *
36430e7468fSPeter Dunlap  * To use an implicit source, a value of NULL is allowed for laddr.
36530e7468fSPeter Dunlap  */
36630e7468fSPeter Dunlap boolean_t
iser_path_exists(idm_sockaddr_t * laddr,idm_sockaddr_t * raddr)36730e7468fSPeter Dunlap iser_path_exists(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr)
36830e7468fSPeter Dunlap {
36930e7468fSPeter Dunlap 
37030e7468fSPeter Dunlap 	ibt_ip_addr_t		remote_ip, local_ip;
37130e7468fSPeter Dunlap 	ibt_path_info_t		path;
37230e7468fSPeter Dunlap 	int			status;
37330e7468fSPeter Dunlap 
37430e7468fSPeter Dunlap 	iser_ib_conv_sockaddr2ibtaddr(raddr, &remote_ip);
37530e7468fSPeter Dunlap 	iser_ib_conv_sockaddr2ibtaddr(laddr, &local_ip);
37630e7468fSPeter Dunlap 
37730e7468fSPeter Dunlap 	status = iser_ib_get_paths(&local_ip, &remote_ip, &path, NULL);
37830e7468fSPeter Dunlap 
37930e7468fSPeter Dunlap 	return ((status == IBT_SUCCESS) ? B_TRUE : B_FALSE);
38030e7468fSPeter Dunlap }
38130e7468fSPeter Dunlap 
38230e7468fSPeter Dunlap /*
38330e7468fSPeter Dunlap  * iser_channel_alloc
38430e7468fSPeter Dunlap  * This function allocates a reliable communication channel between the
38530e7468fSPeter Dunlap  * given endpoints.
38630e7468fSPeter Dunlap  */
38730e7468fSPeter Dunlap iser_chan_t *
iser_channel_alloc(idm_sockaddr_t * laddr,idm_sockaddr_t * raddr)38830e7468fSPeter Dunlap iser_channel_alloc(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr)
38930e7468fSPeter Dunlap {
39030e7468fSPeter Dunlap 	ibt_ip_addr_t		remote_ip, local_ip;
39130e7468fSPeter Dunlap 
39230e7468fSPeter Dunlap 	iser_ib_conv_sockaddr2ibtaddr(raddr, &remote_ip);
39330e7468fSPeter Dunlap 	iser_ib_conv_sockaddr2ibtaddr(laddr, &local_ip);
39430e7468fSPeter Dunlap 
395*1d73e59fSPriya Krishnan 	return (iser_ib_alloc_channel_pathlookup(&local_ip, &remote_ip));
39630e7468fSPeter Dunlap }
39730e7468fSPeter Dunlap 
39830e7468fSPeter Dunlap /*
39930e7468fSPeter Dunlap  * iser_channel_open
40030e7468fSPeter Dunlap  * This function opens the already allocated communication channel between the
40130e7468fSPeter Dunlap  * two endpoints.
40230e7468fSPeter Dunlap  */
40330e7468fSPeter Dunlap iser_status_t
iser_channel_open(iser_chan_t * chan)40430e7468fSPeter Dunlap iser_channel_open(iser_chan_t *chan)
40530e7468fSPeter Dunlap {
40630e7468fSPeter Dunlap 	return (iser_ib_open_rc_channel(chan));
40730e7468fSPeter Dunlap }
40830e7468fSPeter Dunlap 
40930e7468fSPeter Dunlap /*
41030e7468fSPeter Dunlap  * iser_channel_close
41130e7468fSPeter Dunlap  * This function closes the already opened communication channel between the
41230e7468fSPeter Dunlap  * two endpoints.
41330e7468fSPeter Dunlap  */
41430e7468fSPeter Dunlap void
iser_channel_close(iser_chan_t * chan)41530e7468fSPeter Dunlap iser_channel_close(iser_chan_t *chan)
41630e7468fSPeter Dunlap {
41730e7468fSPeter Dunlap 	iser_ib_close_rc_channel(chan);
41830e7468fSPeter Dunlap }
41930e7468fSPeter Dunlap 
42030e7468fSPeter Dunlap /*
42130e7468fSPeter Dunlap  * iser_channel_free
42230e7468fSPeter Dunlap  * This function frees the channel between the given endpoints
42330e7468fSPeter Dunlap  */
42430e7468fSPeter Dunlap void
iser_channel_free(iser_chan_t * chan)42530e7468fSPeter Dunlap iser_channel_free(iser_chan_t *chan)
42630e7468fSPeter Dunlap {
42730e7468fSPeter Dunlap 	iser_ib_free_rc_channel(chan);
42830e7468fSPeter Dunlap }
42930e7468fSPeter Dunlap 
43030e7468fSPeter Dunlap /* ARGSUSED */
43130e7468fSPeter Dunlap static int
iser_ioctl(dev_t devp,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)43230e7468fSPeter Dunlap iser_ioctl(dev_t devp, int cmd, intptr_t arg, int mode, cred_t *credp,
43330e7468fSPeter Dunlap     int *rvalp)
43430e7468fSPeter Dunlap {
43530e7468fSPeter Dunlap 	return (DDI_SUCCESS);
43630e7468fSPeter Dunlap }
437