c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * CDDL HEADER START
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The contents of this file are subject to the terms of the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Common Development and Distribution License (the "License").
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * You may not use this file except in compliance with the License.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * or http://www.opensolaris.org/os/licensing.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * See the License for the specific language governing permissions
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * and limitations under the License.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * When distributing Covered Code, include this CDDL HEADER in each
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * If applicable, add the following below this CDDL HEADER, with the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * fields enclosed by brackets "[]" replaced with your own identifying
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * information: Portions Copyright [yyyy] [name of copyright owner]
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * CDDL HEADER END
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The sol_ucma driver provides the API for librdmacm library for RDMACM
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * functionality.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs will create a minor node with prefix ":ucma",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * which can be opened only by the kernel (cred == kcred).
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_cma driver will open and close the sol_uverb minor
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * device using the Layered Driver Interfaces (See PSARC
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * 2001/769).
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Standard driver includes */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/types.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/modctl.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/sunddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/file.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/errno.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/open.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/cred.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/stat.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/sunddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/conf.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/uio.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/sunldi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/modctl.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Common header files */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_uverbs/sol_uverbs2ucma.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/ofed_kernel.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Kernel Headers for User rdma_cm API */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/rdma/ib_addr.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/rdma/rdma_user_cm.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Kernel rdma_cm API */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/rdma/rdma_cm.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* sol_ucma internal Header files */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_ucma/sol_ucma.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* entry point function prototype declarations */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_attach(dev_info_t *, ddi_attach_cmd_t);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_detach(dev_info_t *, ddi_detach_cmd_t);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_open(dev_t *, int, int, cred_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_close(dev_t, int, int, cred_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_write(dev_t, struct uio *, cred_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_poll(dev_t, short, int, short *, struct pollhead **);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Driver entry points */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic struct cb_ops sol_ucma_cb_ops = {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_open, /* open */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_close, /* close */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* strategy (block) */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* print (block) */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* dump (block) */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* read */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_write, /* write */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* ioctl */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* devmap */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* mmap */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* segmap */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_poll, /* chpoll */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ddi_prop_op, /* prop_op */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar NULL, /* streams */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar D_NEW | D_MP | D_64BIT, /* flags */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar CB_REV /* rev */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar};
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Driver operations */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic struct dev_ops sol_ucma_dev_ops = {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar DEVO_REV, /* struct rev */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0, /* refcnt */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_getinfo, /* getinfo */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nulldev, /* identify */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nulldev, /* probe */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_attach, /* attach */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_detach, /* detach */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* reset */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &sol_ucma_cb_ops, /* cb_ops */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar NULL, /* bus_ops */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar nodev, /* power */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ddi_quiesce_not_needed /* quiesce */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar};
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Module Driver Info */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic struct modldrv sol_ucma_modldrv = {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &mod_driverops,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "Solaris User RDMACM driver",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &sol_ucma_dev_ops
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar};
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Module Linkage */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic struct modlinkage sol_ucma_modlinkage = {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar MODREV_1,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &sol_ucma_modldrv,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar NULL,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar};
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic char *sol_ucma_dbg_str = "sol_ucma";
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_table_t ucma_file_uo_tbl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_table_t ucma_ctx_uo_tbl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ofs_uobj_table_t ucma_mcast_uo_tbl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Function pointers for uverbs functions */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uverbs_get_clnt_hdl_t uverbs_get_hdl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uverbs_qpnum2qphdl_t uverbs_qpnum2qphdl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uverbs_disable_uqpn_mod_t uverbs_disable_uqpn_modify_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uverbs_uqpn_cq_ctrl_t uverbs_uqpn_cq_ctrl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uverbs_set_qp_free_state_t uverbs_set_qp_free_state_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uverbs_flush_qp_t uverbs_flush_qp_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* Global Variables */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_t sol_ucma;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* RDMACM Functions */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_create_id(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_destroy_id(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_bind_addr(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_resolve_addr(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_resolve_route(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_query_route(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_connect(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_listen(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_accept(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_reject(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_disconnect(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_init_qp_attr(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_get_event(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_set_option(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_notify(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_join_mcast(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int sol_ucma_leave_mcast(dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Event callback from sol_cma
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint sol_ucma_evt_hdlr(struct rdma_cm_id *, struct rdma_cm_event *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Internal functions.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ucma_file_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarucma_alloc_file(minor_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ucma_chan_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarucma_alloc_chan(sol_ucma_file_t *, sol_ucma_create_id_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarucma_free_chan(sol_ucma_chan_t *, int);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarget_file_chan(uint32_t, sol_ucma_file_t **, sol_ucma_chan_t **, char *, int);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_route(struct rdma_cm_id *, sol_ucma_query_route_resp_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarusr2rdma_conn_param(struct rdma_ucm_conn_param *, struct rdma_conn_param *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_conn_param(struct rdma_conn_param *, struct rdma_ucm_conn_param *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_ud_param(struct rdma_ud_param *, sol_ucma_ud_param_t *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void sol_ucma_user_objs_init();
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void sol_ucma_user_objs_fini();
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar_init(void)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int error;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "_init()");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_user_objs_init();
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_init(&sol_ucma.ucma_mutex, NULL, MUTEX_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_init(&sol_ucma.ucma_open_cv, NULL, CV_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((error = ldi_ident_from_mod(&sol_ucma_modlinkage,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &sol_ucma.ucma_ldi_ident)) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ldi_ident_from_mod() failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_destroy(&sol_ucma.ucma_open_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_user_objs_fini();
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (error);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag = SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar error = mod_install(&sol_ucma_modlinkage);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (error) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "mod_install() failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ldi_ident_release(sol_ucma.ucma_ldi_ident);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_destroy(&sol_ucma.ucma_open_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_user_objs_fini();
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (error);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "_init(): ret");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (error);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar_info(struct modinfo *modinfop)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (mod_info(&sol_ucma_modlinkage, modinfop));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar_fini(void)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "_fini()");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((ret = mod_remove(&sol_ucma_modlinkage)) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L3(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "sol_ucma, _fini : mod_remove failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ldi_ident_release(sol_ucma.ucma_ldi_ident);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_destroy(&sol_ucma.ucma_open_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_user_objs_fini();
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "_fini(): ret");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int rval;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "attach(%p, %x)", dip, cmd);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar switch (cmd) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar case DDI_ATTACH:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma.ucma_dip != NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "attach: failed, > 1 instance");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_FAILURE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_dip = dip;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rval = ddi_create_minor_node(dip, "sol_ucma", S_IFCHR,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0, DDI_PSEUDO, 0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (rval != DDI_SUCCESS) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "attach: ddi_create_minor_node failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_dip = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_FAILURE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "attach : DDI_ATTACH success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar case DDI_RESUME:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar default:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_FAILURE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "detach(%p, %x)", dip, cmd);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar switch (cmd) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar case DDI_DETACH:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma.ucma_num_file) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "detach : %x files not closed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_num_file);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_FAILURE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_dip = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ddi_remove_minor_node(dip, "sol_ucma");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "detach : DDI_DETACH success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar case DDI_SUSPEND:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar default:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_FAILURE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void **resultp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar switch (cmd) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar case DDI_INFO_DEVT2DEVINFO:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *resultp = (void *)sol_ucma.ucma_dip;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar case DDI_INFO_DEVT2INSTANCE:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *resultp = (void *)0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_SUCCESS);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar default :
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (DDI_FAILURE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_open(dev_t *devp, int flag, int otype, cred_t *credp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *new_filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor_t new_minor;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "open(%p, %x, %x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar devp, flag, otype, credp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_filep = ucma_alloc_file(&new_minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (new_filep == NULL)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EAGAIN);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L4(sol_ucma_dbg_str, "sol_ucma new minor %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * For the first open, ensure that the sol_uverbs driver is attached.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Also get the function pointers for uverbs API functions using
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ddi_modopen() and ddi_modsym() for the sol_uverbs driver.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ldi_open() is done to ensure that sol_uverbs driver is attached,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * even though ddi_modopen is sufficient to get the function pointers
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * for the uverbs APIs
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma.ucma_clnt_hdl_flag == SOL_UCMA_CLNT_HDL_UNINITIALIZED) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int rval, ret_errno;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_INITIALIZING;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((rval = ldi_open_by_name(SOL_UCMA_UVERBS_PATH,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred, &sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_ldi_ident)) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ldi_open_by_name(%s, ...) failed with rval %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_UVERBS_PATH, rval);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ENODEV);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((sol_ucma.ucma_mod_hdl = ddi_modopen("drv/sol_uverbs",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar KRTLD_MODE_FIRST, &ret_errno)) == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modopen(%s, ...) failed", "drv/sol_uverbs");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uverbs_get_hdl_fp = (uverbs_get_clnt_hdl_t)ddi_modsym(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_mod_hdl, SOL_UVERBS_GET_CLNT_HDL, &ret_errno))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modsym(%s, ...) failed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS_GET_CLNT_HDL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uverbs_qpnum2qphdl_fp = (uverbs_qpnum2qphdl_t)ddi_modsym(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_mod_hdl, SOL_UVERBS_QPNUM2QPHDL, &ret_errno))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modsym(%s, ...) failed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS_QPNUM2QPHDL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uverbs_disable_uqpn_modify_fp =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (uverbs_disable_uqpn_mod_t)ddi_modsym(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_mod_hdl, SOL_UVERBS_DISABLE_UQPN_MODIFY,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ret_errno)) == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modsym(%s, ...) failed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS_DISABLE_UQPN_MODIFY);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uverbs_uqpn_cq_ctrl_fp =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (uverbs_uqpn_cq_ctrl_t)ddi_modsym(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_mod_hdl, SOL_UVERBS_UQPN_CQ_CTRL,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ret_errno)) == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modsym(%s, ...) failed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS_UQPN_CQ_CTRL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uverbs_set_qp_free_state_fp =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (uverbs_set_qp_free_state_t)ddi_modsym(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_mod_hdl, SOL_UVERBS_SET_QPFREE_STATE,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ret_errno)) == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modsym(%s, ...) failed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS_SET_QPFREE_STATE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((uverbs_flush_qp_fp =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (uverbs_flush_qp_t)ddi_modsym(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_mod_hdl, SOL_UVERBS_FLUSH_QP,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ret_errno)) == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ddi_modsym(%s, ...) failed",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS_FLUSH_QP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret_errno);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_get_hdl_fp) (&sol_ucma.ucma_ib_clnt_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &sol_ucma.ucma_iw_clnt_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma.ucma_ib_clnt_hdl == NULL &&
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_iw_clnt_hdl == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "uverbs_get_clnt_hdl failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ENODEV);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_INITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_broadcast(&sol_ucma.ucma_open_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else if (sol_ucma.ucma_clnt_hdl_flag ==
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_INITIALIZING) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_wait(&sol_ucma.ucma_open_cv, &sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *devp = makedevice(getmajor(*devp), new_minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "open Success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_close(dev_t dev, int flag, int otype, cred_t *credp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor_t minor;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar genlist_entry_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "close(%x, %x, %x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, flag, otype, credp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor = getminor(dev);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep = (sol_ucma_file_t *)sol_ofs_uobj_get_read(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ucma_file_uo_tbl, minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!filep) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L4(sol_ucma_dbg_str, "close, no dev_t %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /* Disable further event handling for this CM event channel */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (filep->file_evt_close_flag == SOL_UCMA_EVT_PROGRESS) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_wait(&filep->file_evt_close_cv, &filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep->file_evt_close_flag = SOL_UCMA_EVT_DISABLED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Destroy CM IDs which have not been destroyed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * For CMIDs which have been connected, call
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * uverbs_set_qp_free_state(SOL_UVERBS2UCMA_ENABLE_QP_FREE)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * so that QP free will be done when appropriate,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_id_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar while (entry) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *qphdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp = (sol_ucma_chan_t *)entry->data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp->chan_rdma_id)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (chanp->chan_rdma_id)->context = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_destroy_id(chanp->chan_rdma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qphdl = chanp->chan_qp_hdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_qp_hdl = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (qphdl)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_set_qp_free_state_fp) (
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS2UCMA_ENABLE_QP_FREE, 0, qphdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_free_chan(chanp, 1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_id_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /* Flush out any events that have not been acknowledged. */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (filep->file_pending_evt_cnt) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_event_t *evtp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L3(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "close : %d Events not reported to userland",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep->file_pending_evt_cnt);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_evt_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar while (entry) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar evtp = (sol_ucma_event_t *)entry->data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(evtp, sizeof (sol_ucma_event_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(entry, sizeof (genlist_entry_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_evt_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar };
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Module close for sol_uverbs when the last file is closed.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Set the function pointers to sol_uverbs API to NULL
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ddi_modclose() and ldi_close() - sol_uverbs driver
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma.ucma_num_file == 1) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_clnt_hdl_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_CLNT_HDL_UNINITIALIZED;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_get_hdl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qpnum2qphdl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_disable_uqpn_modify_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_uqpn_cq_ctrl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_uqpn_cq_ctrl_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_set_qp_free_state_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_flush_qp_fp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_ib_clnt_hdl = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_iw_clnt_hdl = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ddi_modclose(sol_ucma.ucma_mod_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) ldi_close(sol_ucma.ucma_ldi_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar FREAD | FWRITE, kcred);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_num_file--;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(filep->file_pollhead, sizeof (struct pollhead));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_destroy(&filep->file_evt_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_destroy(&filep->file_evt_close_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&(filep->file_uobj.uo_lock), RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) sol_ofs_uobj_remove(&ucma_file_uo_tbl, &(filep->file_uobj));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&(filep->file_uobj.uo_lock));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&(filep->file_uobj));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikartypedef struct sol_ucma_cmd_table_s {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int (*sol_ucma_cmd_fnc) (dev_t, void *, struct uio *);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint16_t sol_ucma_in_len;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint16_t sol_ucma_out_len;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar} sol_ucma_cmd_table_t;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ucma_cmd_table_t sol_ucma_cmd_table[] = {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_CREATE_ID] = sol_ucma_create_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_resp_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_DESTROY_ID] = sol_ucma_destroy_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_resp_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_BIND_ADDR] = sol_ucma_bind_addr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_bind_addr_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_RESOLVE_ADDR] = sol_ucma_resolve_addr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_resolve_addr_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_RESOLVE_ROUTE] = sol_ucma_resolve_route,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_resolve_route_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_QUERY_ROUTE] = sol_ucma_query_route,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_query_route_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_query_route_resp_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_CONNECT] = sol_ucma_connect,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_connect_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_LISTEN] = sol_ucma_listen,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_listen_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_ACCEPT] = sol_ucma_accept,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_accept_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_REJECT] = sol_ucma_reject,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_reject_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_DISCONNECT] = sol_ucma_disconnect,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_disconnect_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_INIT_QP_ATTR] = sol_ucma_init_qp_attr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_init_qp_attr_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (struct ib_uverbs_qp_attr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_GET_EVENT] = sol_ucma_get_event,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_get_event_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_event_resp_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_GET_OPTION] = NULL,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_SET_OPTION] = sol_ucma_set_option,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_set_option_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_NOTIFY] = sol_ucma_notify,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_notify_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar 0,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_JOIN_MCAST] = sol_ucma_join_mcast,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_join_mcast_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_resp_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar [RDMA_USER_CM_CMD_LEAVE_MCAST] = sol_ucma_leave_mcast,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_t),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_resp_t)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar};
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#define SOL_UCMA_MAX_CMD_DATA 512
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_write(dev_t dev, struct uio *uio, cred_t *credp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_cmd_hdr_t *user_hdrp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *data_buf = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar char uio_data[SOL_UCMA_MAX_CMD_DATA];
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar size_t uio_data_len = uio->uio_resid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "write(%x, %p, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, uio, credp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = uiomove((caddr_t)&uio_data, uio_data_len, UIO_WRITE, uio);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_hdrp = (sol_ucma_cmd_hdr_t *)uio_data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (ret != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "write: uiomove failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (user_hdrp->cmd >=
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_cmd_table) / sizeof (sol_ucma_cmd_table_t)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "open : cmd out of bound 0x%x", user_hdrp->cmd);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!(sol_ucma_cmd_table[user_hdrp->cmd].sol_ucma_cmd_fnc)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "open : Unsupported cmd 0x%x", user_hdrp->cmd);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Check the user passed IN-OUT buffer length, with expected lengths
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma_cmd_table[user_hdrp->cmd].sol_ucma_in_len !=
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (user_hdrp->in)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "write : Invalid Input length cmd %x, in %x expected %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_hdrp->cmd, user_hdrp->in,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_cmd_table[user_hdrp->cmd].sol_ucma_in_len);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ucma_cmd_table[user_hdrp->cmd].sol_ucma_out_len !=
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (user_hdrp->out)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "write : Invalid Output length cmd %x, in %x expected %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_hdrp->cmd, user_hdrp->out,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_cmd_table[user_hdrp->cmd].sol_ucma_out_len);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (user_hdrp->in) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar data_buf = (void *)((char *)uio_data +
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_cmd_hdr_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = (sol_ucma_cmd_table[user_hdrp->cmd].sol_ucma_cmd_fnc)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (dev, data_buf, uio);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /* If the command fails, set back the uio_resid */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (ret)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uio->uio_resid += uio_data_len;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "write : ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_poll(dev_t dev, short events, int anyyet,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar short *reventsp, struct pollhead **phpp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor_t minor = getminor(dev);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "poll(%x, %x)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, events);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!(events & (POLLIN | POLLRDNORM)))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep = (sol_ucma_file_t *)sol_ofs_uobj_get_read(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ucma_file_uo_tbl, minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(filep);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (filep->file_pending_evt_cnt) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *reventsp = POLLIN | POLLRDNORM;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *reventsp = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!anyyet)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *phpp = filep->file_pollhead;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * RDMACM functions.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_create_id(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor_t minor = getminor(dev);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_create_id_t *ucma_id_inp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_create_id_resp_t ucma_id_resp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "create_id(%x, %p), minor %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf, minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id_inp = (sol_ucma_create_id_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(ucma_id_inp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(ucma_id_inp->response.r_laddr);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep = (sol_ucma_file_t *)sol_ofs_uobj_get_read(&ucma_file_uo_tbl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(filep);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp = ucma_alloc_chan(filep, ucma_id_inp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "create_id: No free Channel");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ENODEV);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id_resp.id = chanp->chan_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&ucma_id_resp, (void *)(ucma_id_inp->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&ucma_id_resp, (void *)(ucma_id_inp->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "create_id: copyout fault");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_free_chan(chanp, 1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_rdma_id = rdma_create_id(sol_ucma_evt_hdlr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp, ucma_id_inp->ps);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp->chan_rdma_id == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "create_id: rdma_create_id failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_free_chan(chanp, 1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (chanp->chan_rdma_id)->context = chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_map_id2clnthdl(chanp->chan_rdma_id, sol_ucma.ucma_ib_clnt_hdl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_iw_clnt_hdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "create_id: Return SUCCESS");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_destroy_id(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_destroy_id_t *id_inp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor_t minor;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar genlist_entry_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_destroy_id_resp_t id_resp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "destroy_id(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar id_inp = (sol_ucma_destroy_id_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = id_inp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!get_file_chan(ucma_id, &filep, &chanp, "destroy_id", 0)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor = getminor(dev);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep = (sol_ucma_file_t *)sol_ofs_uobj_get_read(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &ucma_file_uo_tbl, minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!filep) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "destroy_id : filep NULL");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "destroy_id : "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ucma_id %x invalid", ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "destroy_id: chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Event handling, Flush out events pending
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * return the number of events that were acked. Free events not acked.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(filep);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (filep->file_pending_evt_cnt != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L4(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "destroy_id: pending events");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_evt_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar while (entry) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free((void *) (entry->data),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_event_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(entry, sizeof (genlist_entry_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_evt_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar };
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep->file_pending_evt_cnt = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar id_resp.events_reported = chanp->chan_evt_cnt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar id_resp.events_reported = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "destroy_id : chanp %p, "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "evts %x", chanp, id_resp.events_reported);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&id_resp, (void *) (id_inp->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&id_resp, (void *) (id_inp->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "destroy_id: copyout fault");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/* */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp->chan_rdma_id)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (chanp->chan_rdma_id)->context = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_destroy_id(chanp->chan_rdma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_free_chan(chanp, 1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "destroy_id: Success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_bind_addr(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_bind_addr_t *bind_addrp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "bind_addr(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bind_addrp = (sol_ucma_bind_addr_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = bind_addrp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "bind_addr", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "bind_addr - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_bind_addr(chanp->chan_rdma_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (struct sockaddr *)&bind_addrp->addr);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "bind_addr: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_resolve_addr(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_resolve_addr_t *resolve_addrp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "resolve_addr(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resolve_addrp = (sol_ucma_resolve_addr_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = resolve_addrp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "resolve_addr", 1)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "resolve_addr: ucma_id %x invalid", ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "resolve_addr - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_resolve_addr(chanp->chan_rdma_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (struct sockaddr *)&resolve_addrp->src_addr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (struct sockaddr *)&resolve_addrp->dst_addr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resolve_addrp->timeout_ms);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "resolve_addr: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_resolve_route(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_resolve_route_t *resolve_routep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "resolve_route(%x, %p)", dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resolve_routep = (sol_ucma_resolve_route_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = resolve_routep->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "resolve_route", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "resolve_route - chanp %p",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_resolve_route(chanp->chan_rdma_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resolve_routep->timeout_ms);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "resolve_route: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_query_route(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_cm_id *idp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_query_route_t *query_routep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_query_route_resp_t route_info;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "query_route(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar query_routep = (sol_ucma_query_route_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = query_routep->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "query_route", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "query_route - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar idp = chanp->chan_rdma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bzero(&route_info, sizeof (route_info));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma2usr_route(idp, &route_info);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&route_info, (void *) (query_routep->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_query_route_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&route_info, (void *) (query_routep->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_query_route_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "query_route: copyout fault");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "query_route: Succcess");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_connect(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *qphdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_connect_t *connectp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_conn_param conn_param;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_cm_id *idp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "connect(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar connectp = (sol_ucma_connect_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = connectp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "connect", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "connect - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr2rdma_conn_param(&(connectp->conn_param), &conn_param);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uverbs_qpnum2qphdl_fp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uverbs_disable_uqpn_modify_fp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uverbs_uqpn_cq_ctrl_fp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qphdl = (*uverbs_qpnum2qphdl_fp) (conn_param.qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (qphdl == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "connect: "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "invalid QPNum %x", conn_param.qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_disable_uqpn_modify_fp) (conn_param.qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_map_id2qphdl(chanp->chan_rdma_id, qphdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar idp = chanp->chan_rdma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->ps == RDMA_PS_TCP)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) (*uverbs_uqpn_cq_ctrl_fp) (conn_param.qp_num,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS2UCMA_CQ_NOTIFY_DISABLE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_qp_num = conn_param.qp_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_connect(chanp->chan_rdma_id, &conn_param);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * rdma_connect() initiated for this CMID, disable sol_uverbs to
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * free the QP assosiated with this CM ID.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (ret == 0 && idp->ps == RDMA_PS_TCP) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_qp_hdl = qphdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_flags |= SOL_UCMA_CHAN_CONNECT_FLAG;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_set_qp_free_state_fp) (
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS2UCMA_DISABLE_QP_FREE, conn_param.qp_num,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "connect: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_listen(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_listen_t *listenp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "listen(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar listenp = (sol_ucma_listen_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = listenp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "listen", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "listen - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar listenp->backlog = (listenp->backlog == 0 ||
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar listenp->backlog > SOL_UCMA_MAX_LISTEN) ?
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_MAX_LISTEN : listenp->backlog;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_backlog = listenp->backlog;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_listen(chanp->chan_rdma_id, listenp->backlog);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "listen: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_accept(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *qphdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_accept_t *acpt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_conn_param conn_param;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "accept(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar acpt = (sol_ucma_accept_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = acpt->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "accept", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "accept - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((acpt->conn_param).valid) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_cm_id *idp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_user_id = acpt->uid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr2rdma_conn_param(&acpt->conn_param, &conn_param);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uverbs_qpnum2qphdl_fp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qphdl = (*uverbs_qpnum2qphdl_fp) (conn_param.qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (qphdl == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "accept: "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "invalid QPNum %x", conn_param.qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_disable_uqpn_modify_fp) (conn_param.qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_map_id2qphdl(chanp->chan_rdma_id, qphdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar idp = chanp->chan_rdma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->ps == RDMA_PS_TCP)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) (*uverbs_uqpn_cq_ctrl_fp) (conn_param.qp_num,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS2UCMA_CQ_NOTIFY_DISABLE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp->chan_qp_num = conn_param.qp_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_accept(chanp->chan_rdma_id, &conn_param);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_accept(chanp->chan_rdma_id, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "accept: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_reject(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_reject_t *rjct;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "reject(%x, %p)", dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rjct = (sol_ucma_reject_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = rjct->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "reject", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "reject - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_reject(chanp->chan_rdma_id, rjct->private_data,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rjct->private_data_len);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "reject: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_init_qp_attr(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t qp_attr_mask;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_init_qp_attr_t *qp_attr_inp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct ib_uverbs_qp_attr uverbs_qp_attr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct ib_qp_attr qp_attr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "init_qp_attr(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qp_attr_inp = (sol_ucma_init_qp_attr_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = qp_attr_inp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "init_qp_attr", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "init_qp_attr - chanp %p", chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qp_attr.qp_state = qp_attr_inp->qp_state;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if ((ret = rdma_init_qp_attr(chanp->chan_rdma_id, &qp_attr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (int *)&qp_attr_mask)) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "init_qp_attr: ret %x, "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "mask %x", ret, qp_attr_mask);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "init_qp_attr: ret %x, mask %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret, qp_attr_mask);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bzero(&uverbs_qp_attr, sizeof (uverbs_qp_attr));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.qp_attr_mask = qp_attr_mask;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.qp_state = qp_attr.qp_state;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.pkey_index = qp_attr.pkey_index;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.port_num = qp_attr.port_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.qp_access_flags = qp_attr.qp_access_flags;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.qkey = qp_attr.qkey;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.path_mtu = qp_attr.path_mtu;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.dest_qp_num = qp_attr.dest_qp_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.rq_psn = qp_attr.rq_psn;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.max_dest_rd_atomic = qp_attr.max_dest_rd_atomic;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.min_rnr_timer = qp_attr.min_rnr_timer;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.dlid = qp_attr.ah_attr.dlid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (qp_attr.ah_attr.ah_flags) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.is_global = 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(&(qp_attr.ah_attr.grh.dgid),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &(uverbs_qp_attr.ah_attr.grh.dgid), 16);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.grh.flow_label =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qp_attr.ah_attr.grh.flow_label;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.grh.sgid_index =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qp_attr.ah_attr.grh.sgid_index;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.grh.hop_limit =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qp_attr.ah_attr.grh.hop_limit;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.grh.traffic_class =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qp_attr.ah_attr.grh.traffic_class;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.sl = qp_attr.ah_attr.sl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.src_path_bits = qp_attr.ah_attr.src_path_bits;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.static_rate = qp_attr.ah_attr.static_rate;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uverbs_qp_attr.ah_attr.port_num = qp_attr.ah_attr.port_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&uverbs_qp_attr, (void *) (qp_attr_inp->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (uverbs_qp_attr))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&uverbs_qp_attr, (void *) (qp_attr_inp->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (uverbs_qp_attr))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "init_qp_attr : copyout "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_get_event(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor_t minor;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *evt_chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar genlist_entry_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_ucm_get_event *user_evt_inp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_event_t *queued_evt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_ucm_event_resp *user_evt_resp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "get_event(%x, %p)", dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_evt_inp = (struct rdma_ucm_get_event *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor = getminor(dev);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep = (sol_ucma_file_t *)sol_ofs_uobj_get_read(&ucma_file_uo_tbl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar minor);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(filep);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "get_event fmode %x",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uio->uio_fmode);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar while (filep->file_pending_evt_cnt == 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L4(sol_ucma_dbg_str, "get_event: No events");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (uio->uio_fmode & (FNONBLOCK | FNDELAY)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L4(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "get_event: No events, nonblocking");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EAGAIN);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!cv_wait_sig(&filep->file_evt_cv, &filep->file_mutex)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L3(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "get_event: Got Sig");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINTR);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar entry = remove_genlist_head(&filep->file_evt_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(entry);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar queued_evt = (sol_ucma_event_t *)entry->data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(queued_evt);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_evt_resp = &queued_evt->event_resp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "event2usr "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "uid %llx, id %x, event %x, status %x", user_evt_resp->uid,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_evt_resp->id, user_evt_resp->event, user_evt_resp->status);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout((void *)user_evt_resp,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void *)(user_evt_inp->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_event_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout((void *)user_evt_resp,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void *)(user_evt_inp->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_event_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "get_event: copyout "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(entry, sizeof (genlist_entry_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep->file_pending_evt_cnt--;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (queued_evt->event_mcast)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (queued_evt->event_mcast)->mcast_events++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar evt_chanp = queued_evt->event_chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (evt_chanp) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * If the event is RDMA_CM_EVENT_CONNECT_RESPONSE or
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * RDMA_CM_EVENT_ESTABLISHED and the CM ID is for RC,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * enable completion notifications for the QP.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (user_evt_resp->event == RDMA_CM_EVENT_CONNECT_RESPONSE ||
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar user_evt_resp->event == RDMA_CM_EVENT_ESTABLISHED) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_cm_id *idp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int rc;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar idp = evt_chanp->chan_rdma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->ps == RDMA_PS_TCP) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(uverbs_uqpn_cq_ctrl_fp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rc = (*uverbs_uqpn_cq_ctrl_fp)(
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar evt_chanp->chan_qp_num,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS2UCMA_CQ_NOTIFY_ENABLE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (rc) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "uverbs_uqpn_cq_ctrl_fp(%X) "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "failed!!",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar evt_chanp->chan_qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep->file_pending_evt_cnt++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EIO);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /* Bump up backlog for CONNECT_REQUEST events */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&evt_chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (user_evt_resp->event == RDMA_CM_EVENT_CONNECT_REQUEST)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar evt_chanp->chan_backlog++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar evt_chanp->chan_evt_cnt++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&evt_chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "get_event : "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "chan %p, cnt %x", evt_chanp, evt_chanp->chan_evt_cnt);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(entry, sizeof (genlist_entry_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(queued_evt, sizeof (sol_ucma_event_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "get_event: Success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&filep->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * This is used when ULP wants to set the QOS option. This is *not*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * supported by Solaris IB stack, return failure.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_set_option(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * This is used when ULP uses librdmacm but uses out of band connection for CM.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_notify(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_notify_t *notifyp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "notify(%x, %p)", dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar notifyp = (sol_ucma_notify_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = notifyp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chan, "notify", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chan);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_notify(chan->chan_rdma_id, notifyp->event);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (ret)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "notify failed %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "notify Success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_join_mcast(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_join_mcast_t *join_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_create_id_resp_t join_resp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_mcast_t *mcastp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int rc;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "join_mcast(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar join_buf = (sol_ucma_join_mcast_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = join_buf->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chanp, "join_mcast", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mcastp = kmem_zalloc(sizeof (sol_ucma_mcast_t), KM_SLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy((void *)(&(join_buf->addr)), (void *)(&(mcastp->mcast_addr)),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (struct sockaddr));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mcastp->mcast_chan = chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_init(&mcastp->mcast_uobj, NULL, SOL_UCMA_MCAST_TYPE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ofs_uobj_add(&ucma_mcast_uo_tbl, &mcastp->mcast_uobj) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ENOMEM);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mcastp->mcast_uobj.uo_live = 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mcastp->mcast_id = join_resp.id = mcastp->mcast_uobj.uo_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mcastp->mcast_uid = join_buf->uid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rc = rdma_join_multicast(chanp->chan_rdma_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (struct sockaddr *)(&(join_buf->addr)), mcastp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (rc) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "join_mcast: rdma_join_multicast ret %x", rc);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&(mcastp->mcast_uobj.uo_lock), RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) sol_ofs_uobj_remove(&ucma_mcast_uo_tbl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&(mcastp->mcast_uobj.uo_lock));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (rc);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&join_resp, (void *) (join_buf->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&join_resp, (void *) (join_buf->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_create_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "join_mcast: copyout "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "failed");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_leave_multicast(chanp->chan_rdma_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (struct sockaddr *)(&(join_buf->addr)));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&(mcastp->mcast_uobj.uo_lock), RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) sol_ofs_uobj_remove(&ucma_mcast_uo_tbl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&(mcastp->mcast_uobj.uo_lock));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "join_mcast: Return Success");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_leave_mcast(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_destroy_id_t *id_inp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_destroy_id_resp_t id_resp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_mcast_t *mcastp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "leave_mcast(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar id_inp = (sol_ucma_destroy_id_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = id_inp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mcastp = (sol_ucma_mcast_t *)sol_ofs_uobj_get_read(&ucma_mcast_uo_tbl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (mcastp == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "leave_mcast: invalid "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "ID %x", ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chanp = mcastp->mcast_chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma_leave_multicast(chanp->chan_rdma_id, &mcastp->mcast_addr);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar id_resp.events_reported = mcastp->mcast_events;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef _LP64
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&id_resp, (void *) (id_inp->response.r_laddr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (copyout(&id_resp, (void *) (id_inp->response.r_addr),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (sol_ucma_destroy_id_resp_t))) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "leave_mcast: copyout "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "fault");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EFAULT);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&(mcastp->mcast_uobj.uo_lock), RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) sol_ofs_uobj_remove(&ucma_mcast_uo_tbl, &mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&(mcastp->mcast_uobj.uo_lock));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&mcastp->mcast_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "leave_mcast: ret 0");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*ARGSUSED*/
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_disconnect(dev_t dev, void *io_buf, struct uio *uio)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_disconnect_t *disconnectp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar uint32_t ucma_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int ret;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "disconnect(%x, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar dev, io_buf);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar disconnectp = (sol_ucma_disconnect_t *)io_buf;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id = disconnectp->id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (get_file_chan(ucma_id, NULL, &chan, "disconnect", 1))
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (EINVAL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chan);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * For a TCP CMID, which has got the DISCONNECT event, call
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * ibt_flush_qp(), to transition QP to error state.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chan->chan_flush_qp_flag == SOL_UCMA_FLUSH_QP_PENDING) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_flush_qp_flag = SOL_UCMA_FLUSH_QP_DONE;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_flush_qp_fp)(chan->chan_qp_num);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = rdma_disconnect(chan->chan_rdma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_flush_qp_flag = SOL_UCMA_FLUSH_QP_DONE;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "disconnect: ret %x", ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * RDMA ID Event handler
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_evt_hdlr(struct rdma_cm_id *idp, struct rdma_cm_event *eventp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chan, *req_chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *file;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_event_t *ucma_evt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_create_id_t ucma_create_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "ucma_evt_hdlr(%p, %p), "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "event %x, status %x", idp, eventp, eventp->event,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar eventp->status);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan = (sol_ucma_chan_t *)idp->context;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!chan) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str, "ucma_evt_hdlr() - "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "after destroy - %p", idp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar file = chan->chan_file;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!file) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L3(sol_ucma_dbg_str, "ucma_evt_hdlr() - "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "after file destroy - idp %p", idp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (file->file_evt_close_flag == SOL_UCMA_EVT_DISABLED) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L3(sol_ucma_dbg_str, "ucma_evt_hdlr() - "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "after file close - idp %p", idp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar file->file_evt_close_flag = SOL_UCMA_EVT_PROGRESS;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * If the event is RDMA_CM_EVENT_CONNECT_REQUEST, allocate a
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * new chan. The rdma_cm_id for this chan has already been
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * allocated by sol_ofs.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt = kmem_zalloc(sizeof (sol_ucma_event_t), KM_SLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_chan = chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (eventp->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!chan->chan_backlog) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L3(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "backlog exceeded");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar file->file_evt_close_flag = SOL_UCMA_EVT_NONE;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_broadcast(&file->file_evt_close_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(ucma_evt, sizeof (sol_ucma_event_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (-1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_backlog--;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_create_id.uid = chan->chan_user_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar req_chan = ucma_alloc_chan(file, &ucma_create_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (req_chan == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "evt hdlr: No free Channel");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&file->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar file->file_evt_close_flag = SOL_UCMA_EVT_NONE;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_broadcast(&file->file_evt_close_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (-1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar req_chan->chan_rdma_id = idp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&req_chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar idp->context = req_chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&req_chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan = req_chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else if (eventp->event == RDMA_CM_EVENT_DISCONNECTED ||
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar eventp->event == RDMA_CM_EVENT_REJECTED) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *qphdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar /*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Connection has been rejected or disconnected,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Enable uverbs to free QP, if it had been disabled
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * before. sol_uverbs will free the QP appropriately.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar qphdl = chan->chan_qp_hdl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_qp_hdl = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->ps == RDMA_PS_TCP &&
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_flush_qp_flag != SOL_UCMA_FLUSH_QP_DONE &&
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar eventp->event == RDMA_CM_EVENT_DISCONNECTED) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_flush_qp_flag =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UCMA_FLUSH_QP_PENDING;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&chan->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->ps == RDMA_PS_TCP && qphdl)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (*uverbs_set_qp_free_state_fp) (
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_UVERBS2UCMA_ENABLE_QP_FREE, 0, qphdl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else if (eventp->event == RDMA_CM_EVENT_ESTABLISHED &&
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan->chan_flags & SOL_UCMA_CHAN_CONNECT_FLAG)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar eventp->event = RDMA_CM_EVENT_CONNECT_RESPONSE;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_resp.event = eventp->event;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_resp.status = eventp->status;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->ps == RDMA_PS_UDP || idp->ps == RDMA_PS_IPOIB)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma2usr_ud_param(&(eventp->param.ud),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &(ucma_evt->event_resp.param.ud));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma2usr_conn_param(&(eventp->param.conn),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &(ucma_evt->event_resp.param.conn));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (eventp->event == RDMA_CM_EVENT_MULTICAST_JOIN || eventp->event ==
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar RDMA_CM_EVENT_MULTICAST_ERROR) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_mcast = (sol_ucma_mcast_t *)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar eventp->param.ud.private_data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_resp.uid = (ucma_evt->event_mcast)->mcast_uid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_resp.id = (ucma_evt->event_mcast)->mcast_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar } else {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_resp.uid = chan->chan_user_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_evt->event_resp.id = chan->chan_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) add_genlist(&file->file_evt_list, (uintptr_t)ucma_evt, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar file->file_pending_evt_cnt++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "ucma_evt_hdlr-pollwakeup");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar pollwakeup(file->file_pollhead, POLLIN | POLLRDNORM);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_broadcast(&file->file_evt_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar file->file_evt_close_flag = SOL_UCMA_EVT_NONE;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_broadcast(&file->file_evt_close_cv);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&file->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Local Functions
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ucma_file_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarucma_alloc_file(minor_t *new_minorp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *new_file;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_file = kmem_zalloc(sizeof (sol_ucma_file_t), KM_SLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_init(&new_file->file_uobj, NULL, SOL_UCMA_EVT_FILE_TYPE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ofs_uobj_add(&ucma_file_uo_tbl, &new_file->file_uobj) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_file->file_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_file->file_uobj.uo_live = 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar init_genlist(&new_file->file_id_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar init_genlist(&new_file->file_evt_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma.ucma_num_file++;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_ucma.ucma_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "new file num %x, %p",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (new_file->file_uobj).uo_id, new_file);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_init(&new_file->file_mutex, NULL,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar MUTEX_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_init(&new_file->file_evt_cv, NULL, CV_DRIVER,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar cv_init(&new_file->file_evt_close_cv, NULL, CV_DRIVER,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_file->file_pollhead = kmem_zalloc(sizeof (struct pollhead),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar KM_SLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *new_minorp = (minor_t)((new_file->file_uobj).uo_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (new_file);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic sol_ucma_chan_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarucma_alloc_chan(sol_ucma_file_t *filep, sol_ucma_create_id_t *create_id_inp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *new_chanp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "_alloc_chan(%p, %p)",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep, create_id_inp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp = kmem_zalloc(sizeof (sol_ucma_chan_t), KM_SLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_init(&new_chanp->chan_uobj, NULL, SOL_UCMA_CM_ID_TYPE);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (sol_ofs_uobj_add(&ucma_ctx_uo_tbl, &new_chanp->chan_uobj) != 0) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&new_chanp->chan_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_init(&new_chanp->chan_mutex, NULL, MUTEX_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp->chan_uobj.uo_live = 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp->chan_list_ent = add_genlist(&filep->file_id_list,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (uintptr_t)new_chanp, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str, "_alloc_chan - filep %p, "
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "chan_num %x, new_chan %p", filep, (new_chanp->chan_uobj).uo_id,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp->chan_file = filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp->chan_user_id = create_id_inp->uid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar new_chanp->chan_id = (new_chanp->chan_uobj).uo_id;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (new_chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarucma_free_chan(sol_ucma_chan_t *chanp, int delete_list)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_file_t *filep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(chanp);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (delete_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar filep = chanp->chan_file;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(filep);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar delete_genlist(&filep->file_id_list, chanp->chan_list_ent);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&filep->file_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&chanp->chan_mutex);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_enter(&(chanp->chan_uobj.uo_lock), RW_WRITER);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar (void) sol_ofs_uobj_remove(&ucma_ctx_uo_tbl, &(chanp->chan_uobj));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rw_exit(&(chanp->chan_uobj.uo_lock));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_free(&(chanp->chan_uobj));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic int
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarget_file_chan(uint32_t ucma_id, sol_ucma_file_t **filep,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t **chanp, char *caller, int flag_err)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_chan_t *chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (filep)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *filep = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *chanp = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar chan = (sol_ucma_chan_t *)sol_ofs_uobj_get_read(&ucma_ctx_uo_tbl,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chan == NULL) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (flag_err)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L2(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "%s, ucma_id %x invalid", caller, ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar else
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_ucma_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "%s, ucma_id %x invalid", caller, ucma_id);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (-1);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (filep)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *filep = chan->chan_file;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (chanp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *chanp = chan;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_put(&chan->chan_uobj);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_pathrec(struct ib_sa_path_rec *kern_path,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct ib_user_path_rec *usr_path)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(&kern_path->dgid, &usr_path->dgid, 16);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(&kern_path->sgid, &usr_path->sgid, 16);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->dlid = kern_path->dlid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->slid = kern_path->slid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->raw_traffic = kern_path->raw_traffic;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->flow_label = kern_path->flow_label;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->reversible = kern_path->reversible;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->mtu = kern_path->mtu;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->pkey = kern_path->pkey;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->hop_limit = kern_path->hop_limit;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->traffic_class = kern_path->traffic_class;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->sl = kern_path->sl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->mtu_selector = kern_path->mtu_selector;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->rate_selector = kern_path->rate_selector;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->rate = kern_path->rate;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->packet_life_time_selector =
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kern_path->packet_life_time_selector;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->packet_life_time = kern_path->packet_life_time;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_path->preference = kern_path->preference;
fffafeb2cc01732fd6a28ed530e4424094685eceJohnny Cheung usr_path->numb_path = kern_path->numb_path;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_route(struct rdma_cm_id *idp, sol_ucma_query_route_resp_t *resp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_route *routep;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar int i;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar routep = &(idp->route);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (idp->device) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resp->node_guid = idp->device->node_guid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resp->port_num = idp->port_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(&(routep->addr.src_addr), &resp->src_addr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (struct sockaddr_in6));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(&(routep->addr.dst_addr), &resp->dst_addr,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sizeof (struct sockaddr_in6));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar resp->num_paths = routep->num_paths;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar for (i = 0; i < resp->num_paths; i++) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar rdma2usr_pathrec(&(routep->path_rec[i]),
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar &(resp->ib_route[i]));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarusr2rdma_conn_param(struct rdma_ucm_conn_param *usr_conn_paramp,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_conn_param *conn_paramp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->private_data = usr_conn_paramp->private_data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->private_data_len = usr_conn_paramp->private_data_len;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->responder_resources = usr_conn_paramp->responder_resources;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->initiator_depth = usr_conn_paramp->initiator_depth;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->flow_control = usr_conn_paramp->flow_control;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->retry_count = usr_conn_paramp->retry_count;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->rnr_retry_count = usr_conn_paramp->rnr_retry_count;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->srq = usr_conn_paramp->srq;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar conn_paramp->qp_num = usr_conn_paramp->qp_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_conn_param(struct rdma_conn_param *conn_paramp,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct rdma_ucm_conn_param *usr_conn_paramp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->private_data_len = conn_paramp->private_data_len;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bzero(usr_conn_paramp->private_data, RDMA_MAX_PRIVATE_DATA);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (conn_paramp->private_data)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(conn_paramp->private_data,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->private_data,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->private_data_len);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->responder_resources = conn_paramp->responder_resources;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->initiator_depth = conn_paramp->initiator_depth;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->flow_control = conn_paramp->flow_control;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->retry_count = conn_paramp->retry_count;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->rnr_retry_count = conn_paramp->rnr_retry_count;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->srq = conn_paramp->srq;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_conn_paramp->qp_num = conn_paramp->qp_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarrdma2usr_ud_param(struct rdma_ud_param *ud_paramp,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ucma_ud_param_t *usr_ud_paramp)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct ib_ah_attr *ah_attrp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar struct ib_uverbs_ah_attr *usr_ah_attrp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ud_paramp->private_data_len = ud_paramp->private_data_len;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bzero(usr_ud_paramp->private_data, RDMA_MAX_PRIVATE_DATA);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (ud_paramp->private_data)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(ud_paramp->private_data,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ud_paramp->private_data,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ud_paramp->private_data_len);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ud_paramp->qp_num = ud_paramp->qp_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ud_paramp->qkey = ud_paramp->qkey;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ah_attrp = &(ud_paramp->ah_attr);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp = &(usr_ud_paramp->ah_attr);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar bcopy(&(ah_attrp->grh.dgid), &(usr_ah_attrp->grh.dgid[0]), 16);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->grh.flow_label = ah_attrp->grh.flow_label;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->grh.sgid_index = ah_attrp->grh.sgid_index;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->grh.hop_limit = ah_attrp->grh.hop_limit;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->grh.traffic_class = ah_attrp->grh.traffic_class;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->dlid = ah_attrp->dlid;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->sl = ah_attrp->sl;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->src_path_bits = ah_attrp->src_path_bits;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->static_rate = ah_attrp->static_rate;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->is_global = ah_attrp->ah_flags;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar usr_ah_attrp->port_num = ah_attrp->port_num;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_user_objs_init()
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_tbl_init(&ucma_file_uo_tbl, sizeof (sol_ucma_file_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_tbl_init(&ucma_ctx_uo_tbl, sizeof (sol_ucma_chan_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_tbl_init(&ucma_mcast_uo_tbl, sizeof (sol_ucma_mcast_t));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic void
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_ucma_user_objs_fini()
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_tbl_fini(&ucma_file_uo_tbl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_tbl_fini(&ucma_ctx_uo_tbl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_ofs_uobj_tbl_fini(&ucma_mcast_uo_tbl);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}