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 * sol_uverbs_hca.c
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Provides the Solaris OFED User Verbs thin common hca interface for
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sharing of IBT client handle, device list, and asynchronous event
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * delivery.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/vfs.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#ifdef VFS_OPS
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/vfs_opreg.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/vnode.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#endif
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/errno.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/cred.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/uio.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/semaphore.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/sunddi.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/ibtl/ibvti.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/ofa_solaris.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_uverbs/sol_uverbs_hca.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar#include <sys/ib/clients/of/sol_uverbs/sol_uverbs.h>
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarextern char *sol_uverbs_dbg_str;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Globals for managing the list of HCA's and the registered clients.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarkmutex_t sol_uverbs_hca_lock;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarllist_head_t sol_uverbs_hca_list;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarllist_head_t sol_uverbs_client_list;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic uint32_t sol_uverbs_common_hca_initialized = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikartypedef struct sol_uverbs_hca_client_data {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_t list;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_ib_client_t *client;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar} sol_uverbs_hca_client_data_t;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint sol_uverbs_hca_add_client_context(sol_uverbs_hca_t *hca,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_ib_client_t *client);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_register_client
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * client - Pointer to the client structure
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Zero on success, else error code.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The Solaris User Verbs kernel agent provides a single
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * common view of the IBTF devices. This function allows
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Solaris OFA kernel implementations to share this view
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * by registerng a client callback for notification of HCA
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * addtion and removal. Note that when this function is
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * called, the client will get an "add" callback for all
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * existing devices.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ib_register_client(sol_uverbs_ib_client_t *client)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_t *hca;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(client != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_init(&client->list, client);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_add_tail(&client->list, &sol_uverbs_client_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar list_for_each(entry, &sol_uverbs_hca_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar hca = (sol_uverbs_hca_t *)entry->ptr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (client->add &&
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar !sol_uverbs_hca_add_client_context(hca, client)) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar client->add(hca);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_unregister_client
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * client - Pointer to the client structure
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Removes a client registration previously created with
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the sol_uverbs_ib_register_client() call.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ib_unregister_client(sol_uverbs_ib_client_t *client)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_t *entry, *centry, *tmp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_t *hca;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_client_data_t *context;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(client != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar list_for_each(entry, &sol_uverbs_hca_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar hca = (sol_uverbs_hca_t *)entry->ptr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(hca != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (client->remove) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar client->remove(hca);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar centry = hca->client_data_list.nxt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar tmp = centry->nxt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar while (centry != &hca->client_data_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(centry);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context = (sol_uverbs_hca_client_data_t *)centry->ptr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(context != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (context->client == client) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_del(centry);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar kmem_free(context, sizeof (*context));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar centry = tmp;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar tmp = centry->nxt;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_del(&client->list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_get_client_data
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * hca - Pointer to HCA struct passed in the client
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * add function callback.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * client - A pointer to the client structure.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * The client data, or NULL on error.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns the client data associated with the given
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * HCA. The data is set/specified via the
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_set_client_data() function.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ib_get_client_data(sol_uverbs_hca_t *hca,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_ib_client_t *client)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_client_data_t *context;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar void *data = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(hca != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(client != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar list_for_each(entry, &hca->client_data_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context = (sol_uverbs_hca_client_data_t *)entry->ptr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(context != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (context->client == client) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar data = context->data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar break;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (data);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_set_client_data
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * hca - Pointer to HCA struct passed in the client
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * add function.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * client - A pointer to the client structure.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * data - The client data to associate with the HCA.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Sets the client data associated with the given
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * HCA.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ib_set_client_data(sol_uverbs_hca_t *hca,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_ib_client_t *client, void *data)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_client_data_t *context;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(hca != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(client != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar list_for_each(entry, &hca->client_data_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context = (sol_uverbs_hca_client_data_t *)entry->ptr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(context != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (context->client == client) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context->data = data;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar goto out;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_uverbs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "HCA SET CLIENT DATA: No client found for %s\n",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar client->name != NULL ? client->name : "NULL Client Name");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarout:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_register_event_handler
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * handler - Pointer to handler structure
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Zero
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Register to receive ansynchronous notifications
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * for the HCA defined in the handler struct. The notifications
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * are delivered via the callback function defined in the handler
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * struct.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ib_register_event_handler(sol_uverbs_ib_event_handler_t *handler)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(handler != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(handler->hca != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&handler->hca->event_handler_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_init(&handler->list, handler);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_add_tail(&handler->list, &handler->hca->event_handler_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&handler->hca->event_handler_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ib_unregister_event_handler
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * handler - Pointer to handler structure
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Zero
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Unregister a ansynchronous notification handler previously
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * registered via the osl_uverbs_ib_register_event_handler() call.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ib_unregister_event_handler(sol_uverbs_ib_event_handler_t *handler)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(handler != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(handler->hca != NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&handler->hca->event_handler_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_del(&handler->list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&handler->hca->event_handler_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_common_hca_init
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Zero
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Perform initialization required by the common hca client API.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_common_hca_init()
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_init(&sol_uverbs_hca_list, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_init(&sol_uverbs_client_list, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_init(&sol_uverbs_hca_lock, NULL, MUTEX_DRIVER, NULL);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_common_hca_initialized = 1;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_common_hca_fini
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Perform cleanup required by the common hca client API.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarvoid
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_common_hca_fini()
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ASSERT(llist_empty(&sol_uverbs_client_list));
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_common_hca_initialized = 0;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_destroy(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Helpers for internal use only
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_hca_add_client_context
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * hca - Pointer to the hca struct to add a client context.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * client - Pointer to the client.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * 0 on success, else the error.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Create a context for the specified client and attach it to
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * the specified hca.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarstatic
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarint sol_uverbs_hca_add_client_context(sol_uverbs_hca_t *hca,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_ib_client_t *client)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_client_data_t *context;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context = kmem_zalloc(sizeof (*context), KM_NOSLEEP);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (!context) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar SOL_OFS_DPRINTF_L5(sol_uverbs_dbg_str,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar "HCA: Couldn't allocate client context for %s",
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar client->name ? client->name : "Name is NULL");
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ENOMEM);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context->client = client;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar context->data = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_init(&context->list, context);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_add(&context->list, &hca->client_data_list);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&hca->client_data_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (0);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar/*
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Function:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * sol_uverbs_ibt_hdl_to_hca
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Input:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * hca_hdl - IBT handle to an HCA.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Output:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * None
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Returns:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * A pointer to the sol_uverbs HCA structure associated with the handle,
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * or NULL if no associated HCA is found.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Description:
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * Given an IBT hca handle, return the user verbs HCA structure associated
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar * with that handle.
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar */
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_hca_t *
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikarsol_uverbs_ibt_hdl_to_hca(ibt_hca_hdl_t hca_hdl)
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar{
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar llist_head_t *entry;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_t *hca;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar sol_uverbs_hca_t *ret = NULL;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_enter(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar list_for_each(entry, &sol_uverbs_hca_list) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar hca = (sol_uverbs_hca_t *)entry->ptr;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar if (hca->hdl == hca_hdl) {
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar ret = hca;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar break;
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar }
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar mutex_exit(&sol_uverbs_hca_lock);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar return (ret);
c39526b769298791ff5b0b6c5e761f49aabaeb4ePramod Gunjikar}