c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CDDL HEADER START
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * The contents of this file are subject to the terms of the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Common Development and Distribution License (the "License").
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * You may not use this file except in compliance with the License.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * or http://www.opensolaris.org/os/licensing.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * See the License for the specific language governing permissions
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * and limitations under the License.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * When distributing Covered Code, include this CDDL HEADER in each
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * If applicable, add the following below this CDDL HEADER, with the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * fields enclosed by brackets "[]" replaced with your own identifying
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * information: Portions Copyright [yyyy] [name of copyright owner]
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CDDL HEADER END
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
1d99877f5d809f065d76e8ab35d75ce6e4e128a9Alexey Zaytsev * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifndef _RDSV3_IMPL_H
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define _RDSV3_IMPL_H
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/atomic.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * This file is only present in Solaris
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifdef __cplusplus
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaextern "C" {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaextern dev_info_t *rdsv3_dev_info;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define uint16_be_t uint16_t
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define uint32_be_t uint32_t
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define uint64_be_t uint64_t
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * RDS Well known service id
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Format: 0x1h00144Fhhhhhhhh
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * "00144F" is the Sun OUI
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * 'h' can be any hex-decimal digit.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDS_SERVICE_ID 0x1000144F00000001ULL
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Atomic operations
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef unsigned int atomic_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define ATOMIC_INIT(a) a
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define atomic_get(p) (*(p))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define atomic_cmpset_long(p, c, n) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((c == atomic_cas_uint(p, c, n)) ? c : -1)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define atomic_dec_and_test(a) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (atomic_dec_uint_nv((a)) == 0)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define atomic_cmpxchg(a, o, n) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_cas_uint(a, o, n)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifdef _LP64
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define set_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_or_ulong(((volatile ulong_t *)(void *)(p)) + ((b) >> 6), \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota 1ul << ((b) & 0x3f))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define clear_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_and_ulong(((volatile ulong_t *)(void *)(p)) + ((b) >> 6), \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ~(1ul << ((b) & 0x3f)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define test_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (((volatile ulong_t *)(void *)(p))[(b) >> 6] & (1ul << ((b) & 0x3f)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define test_and_set_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_set_long_excl(((ulong_t *)(void *)(p)) + \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((b) >> 6), ((b) & 0x3f))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define test_and_clear_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota !atomic_clear_long_excl(((ulong_t *)(void *)(p)) + ((b) >> 6), \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((b) & 0x3f))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#else
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define set_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_or_uint(((volatile uint_t *)(void *)p) + (b >> 5), \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota 1ul << (b & 0x1f))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define clear_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_and_uint(((volatile uint_t *)(void *)p) + (b >> 5), \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ~(1ul << (b & 0x1f)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define test_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (((volatile uint_t *)(void *)p)[b >> 5] & (1ul << (b & 0x1f)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define test_and_set_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_set_long_excl(((ulong_t *)(void *)p) + (b >> 5), (b & 0x1f))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define test_and_clear_bit(b, p) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota !atomic_clear_long_excl(((ulong_t *)(void *)p) + (b >> 5), (b & 0x1f))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota/*
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota * These macros and/or constants are used instead of Linux
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota * generic_{test,__{clear,set}}_le_bit().
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota */
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#if defined(sparc)
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define LE_BIT_XOR ((BITS_PER_LONG-1) & ~0x7)
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#else
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define LE_BIT_XOR 0
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#endif
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define set_le_bit(b, p) set_bit(b ^ LE_BIT_XOR, p)
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define clear_le_bit(b, p) clear_bit(b ^ LE_BIT_XOR, p)
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define test_le_bit(b, p) test_bit(b ^ LE_BIT_XOR, p)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otauint_t rdsv3_one_sec_in_hz;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define jiffies 100
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define HZ (drv_hztousec(1))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* setting this to PAGESIZE throws build errors */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define PAGE_SIZE 4096 /* xxx - fix this */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define BITS_PER_LONG (sizeof (unsigned long) * 8)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* debug */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_PANIC() cmn_err(CE_PANIC, "Panic forced by RDSV3");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* ERR */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define MAX_ERRNO 4095
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define ERR_PTR(x) ((void *)(uintptr_t)x)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define IS_ERR(ptr) (((uintptr_t)ptr) >= (uintptr_t)-MAX_ERRNO)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define PTR_ERR(ptr) (int)(uintptr_t)ptr
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define MAX_SCHEDULE_TIMEOUT (~0UL>>1)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* list */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* copied and modified list_remove_node */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define list_remove_node(node) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if ((node)->list_next != NULL) { \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (node)->list_prev->list_next = (node)->list_next; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (node)->list_next->list_prev = (node)->list_prev; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (node)->list_next = (node)->list_prev = NULL; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define list_splice(src, dst) { \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_create(dst, (src)->list_size, (src)->list_offset); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_move_tail(dst, src); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_FOR_EACH_LIST_NODE(objp, listp, member) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota for (objp = list_head(listp); objp; objp = list_next(listp, objp))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_FOR_EACH_LIST_NODE_SAFE(objp, tmp, listp, member) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota for (objp = list_head(listp), tmp = (objp != NULL) ? \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_next(listp, objp) : NULL; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota objp; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota objp = tmp, tmp = (objp != NULL) ? \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_next(listp, objp) : NULL)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* simulate wait_queue_head_t */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef struct rdsv3_wait_queue_s {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmutex_t waitq_mutex;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kcondvar_t waitq_cv;
6e18d381c642549b8bb1774a803d3510aec6baafagiri uint_t waitq_waiters;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} rdsv3_wait_queue_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_init_waitqueue(waitqp) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_init(&(waitqp)->waitq_mutex, NULL, MUTEX_DRIVER, NULL); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri cv_init(&(waitqp)->waitq_cv, NULL, CV_DRIVER, NULL); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri (waitqp)->waitq_waiters = 0
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_exit_waitqueue(waitqp) \
6e18d381c642549b8bb1774a803d3510aec6baafagiri ASSERT((waitqp)->waitq_waiters == 0); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_destroy(&(waitqp)->waitq_mutex); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cv_destroy(&(waitqp)->waitq_cv)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_wake_up(waitqp) { \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&(waitqp)->waitq_mutex); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri if ((waitqp)->waitq_waiters) \
6e18d381c642549b8bb1774a803d3510aec6baafagiri cv_signal(&(waitqp)->waitq_cv); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&(waitqp)->waitq_mutex); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_wake_up_all(waitqp) { \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&(waitqp)->waitq_mutex); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri if ((waitqp)->waitq_waiters) \
6e18d381c642549b8bb1774a803d3510aec6baafagiri cv_broadcast(&(waitqp)->waitq_cv); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&(waitqp)->waitq_mutex); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
6e18d381c642549b8bb1774a803d3510aec6baafagiri/* analogous to cv_wait */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_wait_event(waitq, condition) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{ \
6e18d381c642549b8bb1774a803d3510aec6baafagiri mutex_enter(&(waitq)->waitq_mutex); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri (waitq)->waitq_waiters++; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota while (!(condition)) { \
6e18d381c642549b8bb1774a803d3510aec6baafagiri cv_wait(&(waitq)->waitq_cv, &(waitq)->waitq_mutex); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota } \
6e18d381c642549b8bb1774a803d3510aec6baafagiri (waitq)->waitq_waiters--; \
6e18d381c642549b8bb1774a803d3510aec6baafagiri mutex_exit(&(waitq)->waitq_mutex); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
6e18d381c642549b8bb1774a803d3510aec6baafagiri/* analogous to cv_wait_sig */
6e18d381c642549b8bb1774a803d3510aec6baafagiri#define rdsv3_wait_sig(waitqp, condition) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota( \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{ \
6e18d381c642549b8bb1774a803d3510aec6baafagiri int cv_return = 1; \
6e18d381c642549b8bb1774a803d3510aec6baafagiri mutex_enter(&(waitqp)->waitq_mutex); \
6e18d381c642549b8bb1774a803d3510aec6baafagiri (waitqp)->waitq_waiters++; \
6e18d381c642549b8bb1774a803d3510aec6baafagiri while (!(condition)) { \
6e18d381c642549b8bb1774a803d3510aec6baafagiri cv_return = cv_wait_sig(&(waitqp)->waitq_cv, \
6e18d381c642549b8bb1774a803d3510aec6baafagiri &(waitqp)->waitq_mutex); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (cv_return == 0) { \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota } \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota } \
6e18d381c642549b8bb1774a803d3510aec6baafagiri (waitqp)->waitq_waiters--; \
6e18d381c642549b8bb1774a803d3510aec6baafagiri mutex_exit(&(waitqp)->waitq_mutex); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cv_return; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define SOCK_DEAD 1ul
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* socket */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef struct rsock {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sock_upper_handle_t sk_upper_handle;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sock_upcalls_t *sk_upcalls;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmutex_t sk_lock;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ulong_t sk_flag;
6e18d381c642549b8bb1774a803d3510aec6baafagiri rdsv3_wait_queue_t *sk_sleep; /* Also protected by rs_recv_lock */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int sk_sndbuf;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int sk_rcvbuf;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota atomic_t sk_refcount;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_sock *sk_protinfo;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} rsock_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef struct rdsv3_conn_info_s {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota uint32_be_t c_laddr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota uint32_be_t c_faddr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} rdsv3_conn_info_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* WQ */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef struct rdsv3_workqueue_struct_s {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmutex_t wq_lock;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota uint_t wq_state;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int wq_pending;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_t wq_queue;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} rdsv3_workqueue_struct_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rdsv3_work_s;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef void (*rdsv3_work_func_t)(struct rdsv3_work_s *);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef struct rdsv3_work_s {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota list_node_t work_item;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_work_func_t func;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} rdsv3_work_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* simulate delayed_work */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otatypedef struct rdsv3_delayed_work_s {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota kmutex_t lock;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_work_t work;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota timeout_id_t timeid;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_workqueue_struct_t *wq;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota} rdsv3_delayed_work_t;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_INIT_WORK(wp, f) (wp)->func = f
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_INIT_DELAYED_WORK(dwp, f) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (dwp)->work.func = f; \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_init(&(dwp)->lock, NULL, MUTEX_DRIVER, NULL); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (dwp)->timeid = 0
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* simulate scatterlist */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rdsv3_scatterlist {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota caddr_t vaddr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota uint_t length;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ibt_wr_ds_t *sgl;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ibt_mi_hdl_t mihdl;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota};
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_sg_page(scat) (scat)->vaddr
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_sg_len(scat) (scat)->length
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_sg_set_page(scat, pg, len, off) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (scat)->vaddr = (caddr_t)(pg + off); \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (scat)->length = len
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define rdsv3_ib_sg_dma_len(dev, scat) rdsv3_sg_len(scat)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* copied from sys/socket.h */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#if defined(__sparc)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* To maintain backward compatibility, alignment needs to be 8 on sparc. */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define _CMSG_HDR_ALIGNMENT 8
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#else
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* for __i386 (and other future architectures) */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define _CMSG_HDR_ALIGNMENT 4
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif /* defined(__sparc) */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * The cmsg headers (and macros dealing with them) were made available as
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * part of UNIX95 and hence need to be protected with a _XPG4_2 define.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define _CMSG_DATA_ALIGNMENT (sizeof (int))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define _CMSG_HDR_ALIGN(x) (((uintptr_t)(x) + _CMSG_HDR_ALIGNMENT - 1) & \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ~(_CMSG_HDR_ALIGNMENT - 1))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define _CMSG_DATA_ALIGN(x) (((uintptr_t)(x) + _CMSG_DATA_ALIGNMENT - 1) & \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ~(_CMSG_DATA_ALIGNMENT - 1))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define CMSG_DATA(c) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((unsigned char *)_CMSG_DATA_ALIGN((struct cmsghdr *)(c) + 1))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define CMSG_FIRSTHDR(m) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (((m)->msg_controllen < sizeof (struct cmsghdr)) ? \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (struct cmsghdr *)0 : (struct cmsghdr *)((m)->msg_control))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define CMSG_NXTHDR(m, c) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (((c) == 0) ? CMSG_FIRSTHDR(m) : \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((((uintptr_t)_CMSG_HDR_ALIGN((char *)(c) + \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((struct cmsghdr *)(c))->cmsg_len) + sizeof (struct cmsghdr)) > \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota (((uintptr_t)((struct msghdr *)(m))->msg_control) + \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((uintptr_t)((struct msghdr *)(m))->msg_controllen))) ? \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((struct cmsghdr *)0) : \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((struct cmsghdr *)_CMSG_HDR_ALIGN((char *)(c) + \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((struct cmsghdr *)(c))->cmsg_len))))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* Amount of space + padding needed for a message of length l */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define CMSG_SPACE(l) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((unsigned int)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l)))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* Value to be used in cmsg_len, does not include trailing padding */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define CMSG_LEN(l) \
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ((unsigned int)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)) + (l))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* OFUV -> IB */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_IBDEV2HCAHDL(device) (device)->hca_hdl
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_QP2CHANHDL(qp) (qp)->ibt_qp
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_PD2PDHDL(pd) (pd)->ibt_pd
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#define RDSV3_CQ2CQHDL(cq) (cq)->ibt_cq
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rdsv3_hdrs_mr {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ibt_lkey_t lkey;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota caddr_t addr;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota size_t size;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ibt_mr_hdl_t hdl;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota};
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/* rdsv3_impl.c */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_trans_init();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaboolean_t rdsv3_capable_interface(struct lifreq *lifrp);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_do_ip_ioctl(ksocket_t so4, void **ipaddrs, int *size, int *nifs);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_do_ip_ioctl_old(ksocket_t so4, void **ipaddrs, int *size, int *nifs);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaboolean_t rdsv3_isloopback(ipaddr_t addr);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_cancel_delayed_work(rdsv3_delayed_work_t *dwp);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_flush_workqueue(rdsv3_workqueue_struct_t *wq);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_queue_work(rdsv3_workqueue_struct_t *wq, rdsv3_work_t *wp);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_queue_delayed_work(rdsv3_workqueue_struct_t *wq,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_delayed_work_t *dwp, uint_t delay);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rsock *rdsv3_sk_alloc();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_sock_init_data(struct rsock *sk);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_sock_exit_data(struct rsock *sk);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_destroy_task_workqueue(rdsv3_workqueue_struct_t *wq);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_workqueue_struct_t *rdsv3_create_task_workqueue(char *name);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_conn_constructor(void *buf, void *arg, int kmflags);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_conn_destructor(void *buf, void *arg);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_conn_compare(const void *conn1, const void *conn2);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_loop_init();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_mr_compare(const void *mr1, const void *mr2);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_put_cmsg(struct nmsghdr *msg, int level, int type, size_t size,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota void *payload);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint rdsv3_verify_bind_address(ipaddr_t addr);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otauint16_t rdsv3_ip_fast_csum(void *buffer, size_t length);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otauint_t rdsv3_ib_dma_map_sg(struct ib_device *dev, struct rdsv3_scatterlist
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *scat, uint_t num);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_ib_dma_unmap_sg(ib_device_t *dev, struct rdsv3_scatterlist *scat,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota uint_t num);
1a561c7696fb9440160a24ca56e8dd264a4cd8abEiji Otastatic inline void
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_sk_sock_hold(struct rsock *sk)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_inc_32(&sk->sk_refcount);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
1a561c7696fb9440160a24ca56e8dd264a4cd8abEiji Otastatic inline void
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_sk_sock_put(struct rsock *sk)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (atomic_dec_and_test(&sk->sk_refcount))
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_sock_exit_data(sk);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
1a561c7696fb9440160a24ca56e8dd264a4cd8abEiji Otastatic inline int
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_sk_sock_flag(struct rsock *sk, uint_t flag)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (test_bit(flag, &sk->sk_flag));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
1a561c7696fb9440160a24ca56e8dd264a4cd8abEiji Otastatic inline void
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_sk_sock_orphan(struct rsock *sk)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota set_bit(SOCK_DEAD, &sk->sk_flag);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define rdsv3_sndtimeo(a, b) b ? 0 : 3600 /* check this value on linux */
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota#define rdsv3_rcvtimeo(a, b) b ? 0 : 3600 /* check this value on linux */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid rdsv3_ib_free_conn(void *arg);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifdef __cplusplus
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif /* _RDSV3_IMPL_H */