1 /*
  2  * CDDL HEADER START
  3  *
  4  * The contents of this file are subject to the terms of the
  5  * Common Development and Distribution License, Version 1.0 only
  6  * (the "License").  You may not use this file except in compliance
  7  * with the License.
  8  *
  9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 10  * or http://www.opensolaris.org/os/licensing.
 11  * See the License for the specific language governing permissions
 12  * and limitations under the License.
 13  *
 14  * When distributing Covered Code, include this CDDL HEADER in each
 15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 16  * If applicable, add the following below this CDDL HEADER, with the
 17  * fields enclosed by brackets "[]" replaced with your own identifying
 18  * information: Portions Copyright [yyyy] [name of copyright owner]
 19  *
 20  * CDDL HEADER END
 21  */
 22 /*
 23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 24  * Use is subject to license terms.
 25  */
 26 
 27  /* Copyright (c) 2006, The Ohio State University. All rights reserved.
 28   *
 29   * Portions of this source code is developed by the team members of
 30   * The Ohio State University's Network-Based Computing Laboratory (NBCL),
 31   * headed by Professor Dhabaleswar K. (DK) Panda.
 32   *
 33   * Acknowledgements to contributions from developors:
 34   *   Ranjit Noronha: noronha@cse.ohio-state.edu
 35   *   Lei Chai      : chail@cse.ohio-state.edu
 36   *   Weikuan Yu    : yuw@cse.ohio-state.edu
 37   *
 38   */
 39 
 40 #ifndef _RPC_RPC_RDMA_H
 41 #define _RPC_RPC_RDMA_H
 42 
 43 #pragma ident   "@(#)rpc_rdma.h 1.9     05/06/08 SMI"
 44 
 45 #include <rpc/rpc.h>
 46 #include <rpc/rpc_sztypes.h>
 47 #include <sys/sunddi.h>
 48 #include <sys/sunldi.h>
 49 
 50 #ifdef __cplusplus
 51 extern "C" {
 52 #endif
 53 
 54 #define RPCRDMA_VERS    1       /* Version of the RPC over RDMA protocol */ 
 55 #define RDMATF_VERS     1       /* Version of the API used by RPC for RDMA */
 56 #define RDMATF_VERS_1   1       /* Current version of RDMATF */
 57 
 58 /* #define DYNAMIC_CREDIT_CONTROL 1 */
 59 #define SERVER_REG_CACHE         
 60 /*#define ASYNC_SERVER_DEREG */
 61 #define ASYNC_CLIENT_DEREG
 62 /*#define RPC_RDMA_INLINE  */
 63 #ifdef RPC_RDMA_INLINE   /* Increase to some super-large values */
 64 #define RDMA_MINCHUNK   262144
 65 #define RPC_MSG_SZ      262144 
 66 #define RPC_CL_SZ       262144
 67 #define MINCHUNK        262144
 68 #define RPC_BUF_SIZE    262144*2
 69 #else
 70 /*
 71  * RDMA chunk size
 72  */
 73 #define RDMA_MINCHUNK   1024
 74 /*
 75  * The size of an RPC call or reply message
 76  */
 77 #define RPC_MSG_SZ  1024
 78 
 79 /*
 80  * Storage for a chunk list
 81  */
 82 #define RPC_CL_SZ  1024
 83 
 84 /*
 85  * Chunk size
 86  */
 87 #define MINCHUNK  1024
 88 
 89 /*
 90  * Size of receive buffer
 91  */
 92 #define RPC_BUF_SIZE    2048
 93 #endif
 94 
 95 #define NOWAIT  0       /* don't wait for operation of complete */
 96 #define WAIT    1       /* wait and ensure that operation is complete */
 97 
 98 /*
 99  * RDMA xdr buffer control and other control flags. Add new flags here,
100  * set them in private structure for xdr over RDMA in xdr_rdma.c
101  */
102 #define RDMA_NOCHUNK            0x1
103 
104 #define LONG_REPLY_LEN 65536
105 
106 extern int credit_control_debug;
107 extern int rib_long_reply_debug;
108 extern int rdma_long_reply_debug;
109 extern int rdma_xdr_long_reply_debug;
110 extern int rdma_wlist_xdr_debug;
111 extern int rdma_wlist_clnt_debug;
112 extern int rdma_wlist_svc_debug;
113 extern int rdma_wlist_memreg_debug;
114 extern int rdma_wlist_verbose_debug;
115 
116 
117 #define RDMA_BUFS_RQST          128       /* Num bufs requested by client */
118 #define RDMA_BUFS_GRANT         126       /* Num bufs granted by server */ 
119 
120 /*
121  * Credit Control Structures.
122  */
123 typedef enum rdma_cc_type {
124        RDMA_CC_CLNT,           /* CONN is for a client */
125        RDMA_CC_SRV             /* CONN is for a server */
126 } rdma_cc_type_t;
127 
128 /*
129  * Client side credit control data structure.
130  */
131 typedef struct rdma_clnt_cred_ctrl {
132         uint32_t        clnt_cc_granted_ops;
133         uint32_t        clnt_cc_in_flight_ops;
134         kcondvar_t      clnt_cc_cv;
135 } rdma_clnt_cred_ctrl_t;
136 
137 /*
138  * Server side credit control data structure.
139  */
140 typedef struct rdma_srv_cred_ctrl {
141         uint32_t        srv_cc_buffers_granted;
142         uint32_t        srv_cc_cur_buffers_used;
143         uint32_t        srv_cc_posted;
144         uint32_t        srv_cc_max_buf_size;    /* to be determined by CCP */
145         uint32_t        srv_cc_cur_buf_size;    /* to be determined by CCP */
146 } rdma_srv_cred_ctrl_t;
147 
148 typedef enum {
149     RPCCALL_RCHUNK,
150     RPCCALL_NORCHUNK
151 }rpccall_read_t;
152 
153 typedef enum {
154     RPCCALL_WLIST,
155     RPCCALL_WCHUNK,
156     RPCCALL_NOWRITE
157 }rpccall_write_t;
158 
159 /*
160  * Return codes from RDMA operations
161  */
162 typedef enum {
163 
164         RDMA_SUCCESS = 0,       /* successful operation */
165 
166         RDMA_INVAL = 1,         /* invalid parameter */
167         RDMA_TIMEDOUT = 2,      /* operation timed out */
168         RDMA_INTR = 3,          /* operation interrupted */
169         RDMA_NORESOURCE = 4,    /* insufficient resource */
170         /*
171          * connection errors
172          */
173         RDMA_REJECT = 5,        /* connection req rejected */
174         RDMA_NOLISTENER = 6,    /* no listener on server */
175         RDMA_UNREACHABLE = 7,   /* host unreachable */
176         RDMA_CONNLOST = 8,      /* connection lost */
177 
178         RDMA_XPRTFAILED = 9,    /* RDMA transport failed */
179         RDMA_PROTECTERR = 10,   /* memory protection error */
180         RDMA_OVERRUN = 11,      /* transport overrun */
181         RDMA_RECVQEMPTY = 12,   /* incoming pkt dropped, recv q empty */
182         RDMA_PROTFAILED = 13,   /* RDMA protocol failed */
183         RDMA_NOTSUPP = 14,      /* requested feature not supported */
184         RDMA_REMOTERR = 15,     /* error at remote end */
185         /*
186          * RDMATF errors
187          */
188         RDMA_BADVERS = 16,      /* mismatch RDMATF versions */
189         RDMA_REG_EXIST = 17,    /* RDMATF registration already exists */
190 
191         /*
192          * fallback error
193          */
194         RDMA_FAILED = 18        /* generic error */
195 } rdma_stat;
196 
197 /*
198  * Memory region context. This is an RDMA provider generated
199  * handle for a registered arbitrary size contiguous virtual
200  * memory. The RDMA Interface Adapter needs this for local or
201  * remote memory access.
202  *
203  * The mrc_rmr field holds the remote memory region context
204  * which is sent over-the-wire to provide the remote host
205  * with RDMA access to the memory region.
206  */
207 struct mrc {
208         uint32_t        mrc_rmr;        /* Remote MR context, sent OTW */
209         union {
210                 struct mr {
211                         uint32_t        lmr;    /* Local MR context */
212                         uint64_t        linfo;  /* Local memory info */
213                         uint64_t        lma;    /* Local Mem Area Hdl */
214                 } mr;
215         } lhdl;
216 };
217 
218 #define mrc_lmr         lhdl.mr.lmr
219 #define mrc_linfo       lhdl.mr.linfo
220 #define mrc_lma         lhdl.mr.lma             /* FMR : Mem Area Hdl */ 
221 /*
222  * The XDR offset value is used by the XDR
223  * routine to identify the position in the
224  * RPC message where the opaque object would
225  * normally occur. Neither the data content
226  * of the chunk, nor its size field are included
227  * in the RPC message.  The XDR offset is calculated
228  * as if the chunks were present.
229  *
230  * The remaining fields identify the chunk of data
231  * on the sender.  The c_memhandle identifies a
232  * registered RDMA memory region and the c_addr
233  * and c_len fields identify the chunk within it.
234  */
235 
236 #ifdef SERVER_REG_CACHE
237 typedef struct rib_lrc_entry {
238    struct rib_lrc_entry *forw;
239    struct rib_lrc_entry *back;
240    char *lrc_buf;
241    
242    uint32_t lrc_len;
243    void  *avl_node;
244    bool_t registered;
245 
246    struct mrc lrc_mhandle;
247    bool_t lrc_on_freed_list;
248 } rib_lrc_entry_t;
249 #endif
250 
251 struct clist {
252         uint32          c_xdroff;       /* XDR offset */
253         uint32          c_len;          /* Length */
254         struct mrc      c_smemhandle;   /* src memory handle */
255         uint64          c_ssynchandle;  /* src sync handle */
256         uint64          c_saddr;        /* src address */
257         struct mrc      c_dmemhandle;   /* dst memory handle */
258         uint64          c_dsynchandle;  /* dst sync handle */
259         uint64          c_daddr;        /* dst address */
260         struct as       *c_adspc;       /* address space for saddr/daddr */
261         page_t          **c_dpplist;    /* page list for dest vaddr */
262         uint64          long_reply_buf;
263         struct clist    *c_next;        /* Next chunk */
264 };
265 
266 typedef struct clist clist;
267 
268 extern struct clist empty_cl;
269 
270 /*
271  * FTDO: max 4 meg wlist xfer size
272  * This is defined because the rfs3_tsize service requires
273  * svc_req struct (which we don't have that in krecv).
274  */
275 #define MAX_SVC_XFER_SIZE (4*1024*1024)
276 
277 enum rdma_proc {
278         RDMA_MSG        = 0,    /* chunk list and RPC msg follow */
279         RDMA_NOMSG      = 1,    /* only chunk list follows */
280         RDMA_MSGP       = 2,    /* chunk list and RPC msg with padding follow */
281         RDMA_DONE       = 3     /* signal completion of chunk transfer */
282 };
283 
284 /*
285  * Listener information for a service
286  */
287 struct rdma_svc_data {
288         queue_t         q;      /* queue_t to place incoming pkts */
289         int             active; /* If active, after registeration startup */
290         rdma_stat       err_code;       /* Error code from plugin layer */
291         int32_t         svcid;          /* RDMA based service identifier */
292 };
293 
294 /*
295  * Per RDMA plugin module information.
296  * Will be populated by each plugin
297  * module during its initialization.
298  */
299 typedef struct rdma_mod {
300         char            *rdma_api;              /* "kvipl", "ibtf", etc */
301         uint_t          rdma_version;           /* RDMATF API version */
302         int             rdma_count;             /* # of devices */
303         struct rdmaops  *rdma_ops;              /* rdma op vector for api */
304 } rdma_mod_t;
305 
306 /*
307  * Registry of RDMA plugins
308  */
309 typedef struct rdma_registry {
310         rdma_mod_t      *r_mod;         /* plugin mod info */
311         struct rdma_registry *r_next;   /* next registered RDMA plugin */
312 } rdma_registry_t;
313 
314 /*
315  * RDMA transport information
316  */
317 typedef struct rdma_info {
318         uint_t  addrlen;        /* address length */
319         uint_t  mts;            /* max transfer size */
320         uint_t  mtu;            /* native mtu size of unlerlying network */
321 } rdma_info_t;
322 
323 /*
324  * RDMA Connection information
325  */
326 typedef struct conn {
327         rdma_mod_t      *c_rdmamod;     /* RDMA transport info for conn */
328         struct netbuf   c_raddr;        /* remote address */
329         struct netbuf   c_laddr;        /* local address */
330         int             c_ref;          /* no. of clients of connection */
331         struct conn     *c_next;        /* next in list of connections */
332         struct conn     *c_prev;        /* prev in list of connections */
333         caddr_t         c_private;      /* transport specific stuff */
334 
335 #define C_IDLE          0x80000000
336 #define C_CONN_PEND     0x40000000
337 #define C_CONNECTED     0x20000000
338 #define C_ERROR         0x10000000
339 #define C_DISCONN_PEND  0x08000000
340 #define C_REMOTE_DOWN   0x04000000
341 
342         uint_t          c_state;        /* state of connection */
343         rdma_cc_type_t  c_cc_type;      /* client or server, for credit cntrl */
344         union {
345                 rdma_clnt_cred_ctrl_t   c_clnt_cc;
346                 rdma_srv_cred_ctrl_t    c_srv_cc;
347         } rdma_conn_cred_ctrl_u;
348         kmutex_t        c_lock;         /* protect c_state and c_ref fields */
349         kcondvar_t      c_cv;           /* to signal when pending is done */
350 #if defined (CLNT_INTERRUPT_COAL)
351         uint_t          c_count;
352 #endif
353 } CONN;
354 
355 
356 /*
357  * Memory management for the RDMA buffers
358  */
359 /*
360  * RDMA buffer types
361  */
362 typedef enum {
363         SEND_BUFFER,    /* buf for send msg */
364         SEND_DESCRIPTOR, /* buf used for send msg descriptor in plugins only */
365         RECV_BUFFER,    /* buf for recv msg */
366         RECV_DESCRIPTOR, /* buf used for recv msg descriptor in plugins only */
367         CHUNK_BUFFER    /* chunk buf used in RDMATF only and not in plugins */
368 } rdma_btype;
369 
370 /*
371  * RDMA buffer information
372  */
373 typedef struct rdma_buf {
374         rdma_btype      type;   /* buffer type */
375         int             len;    /* length of buffer */
376         caddr_t         addr;   /* buffer address */
377         struct mrc      handle; /* buffer registration handle */
378 #ifdef SERVER_REG_CACHE
379         rib_lrc_entry_t *long_reply_buf;
380 #endif
381 } rdma_buf_t;
382 
383 /*
384  * Data transferred from plugin interrupt to svc_queuereq()
385  */
386 struct recv_data {
387         CONN            *conn;
388         int             status;
389         rdma_buf_t      rpcmsg;
390 };
391 
392 /*
393  * Operations vector for RDMA transports.
394  */
395 typedef struct rdmaops {
396         /* Network */
397         rdma_stat       (*rdma_reachable)(int addr_type, struct netbuf *,
398                                                 void **handle);
399         /* Connection */
400         rdma_stat       (*rdma_get_conn)(struct netbuf *, int addr_type,
401                                                 void *, CONN **);
402         rdma_stat       (*rdma_rel_conn)(CONN *);
403         /* Server side listner start and stop routines */
404         void            (*rdma_svc_listen)(struct rdma_svc_data *);
405         void            (*rdma_svc_stop)(struct rdma_svc_data *);
406         /* Memory */
407         rdma_stat       (*rdma_regmem)(CONN *, caddr_t , caddr_t, uint_t, struct mrc *); 
408         rdma_stat       (*rdma_deregmem)(CONN *, caddr_t, struct mrc);
409 #ifdef SERVER_REG_CACHE 
410         rdma_stat       (*rdma_regmemsync)(CONN *, caddr_t ,caddr_t, uint_t, 
411                                 struct mrc *, void **, void *); 
412         rdma_stat       (*rdma_deregmemsync)(CONN *, caddr_t, struct mrc, 
413                                 void *, void *); 
414 #else 
415         rdma_stat       (*rdma_regmemsync)(CONN *, caddr_t ,caddr_t, uint_t, 
416                                 struct mrc *, void **);
417         rdma_stat       (*rdma_deregmemsync)(CONN *, caddr_t, struct mrc,
418                                 void *);
419 
420 #endif
421         rdma_stat       (*rdma_syncmem)(CONN *, void *, caddr_t, int, int);
422         /* Buffer */
423         rdma_stat       (*rdma_buf_alloc)(CONN *, rdma_buf_t *);
424         void            (*rdma_buf_free)(CONN *, rdma_buf_t *);
425         /* Transfer */
426         rdma_stat       (*rdma_send)(CONN *, clist *, uint32_t);
427 #if defined (CLNT_INTERRUPT_COAL)
428         rdma_stat       (*rdma_send_bl)(CONN *, clist *, uint32_t);
429 #endif
430 #if defined(ASYNC_SERVER_DEREG)
431         rdma_stat       (*rdma_send_nw)(CONN *, clist *, uint32_t, caddr_t, caddr_t , int, caddr_t ,int, int, int);
432 #endif
433         rdma_stat       (*rdma_send_resp)(CONN *, clist *, uint32_t);
434         rdma_stat       (*rdma_clnt_recvbuf)(CONN *, clist *, uint32_t);
435         rdma_stat       (*rdma_svc_recvbuf)(CONN *, clist *);
436         rdma_stat       (*rdma_recv)(CONN *, clist **, uint32_t);
437         /* RDMA */
438         rdma_stat       (*rdma_read)(CONN *, clist *, int);
439         rdma_stat       (*rdma_write)(CONN *, clist *, int);
440         /* INFO */
441         rdma_stat       (*rdma_getinfo)(rdma_info_t *info);
442 #ifdef SERVER_REG_CACHE
443         rib_lrc_entry_t *(*rdma_get_server_cache_buf)(CONN *,uint32_t);
444         void            (*rdma_free_server_cache_buf)(CONN *, rib_lrc_entry_t *);
445 #endif
446 #ifdef DYNAMIC_CREDIT_CONTROL
447         void            (*rdma_get_resource_info)(CONN *, int *, int *);
448 #endif
449 #if defined(ASYNC_CLIENT_DEREG)
450         void    (*insert_queue)(CONN *, clist *);
451 #endif
452 
453 } rdmaops_t;
454 
455 /*
456  * RDMA operations.
457  */
458 #define RDMA_REACHABLE(rdma_ops, addr_type, addr, handle)       \
459         (*(rdma_ops)->rdma_reachable)(addr_type, addr, handle)
460 
461 #define RDMA_GET_CONN(rdma_ops, addr, addr_type, handle, conn)  \
462         (*(rdma_ops)->rdma_get_conn)(addr, addr_type, handle, conn)
463 
464 #define RDMA_REL_CONN(conn)     \
465         (*(conn)->c_rdmamod->rdma_ops->rdma_rel_conn)(conn)
466 
467 #define RDMA_REGMEM(conn, adsp, buff, len, handle)      \ 
468         (*(conn)->c_rdmamod->rdma_ops->rdma_regmem)(conn, adsp, buff, len, handle) 
469 
470 #define RDMA_DEREGMEM(conn, buff, handle)       \
471         (*(conn)->c_rdmamod->rdma_ops->rdma_deregmem)(conn, buff, handle)
472 
473 #ifdef SERVER_REG_CACHE 
474 #define RDMA_REGMEMSYNC(conn, adsp, buff, len, handle, synchandle, lrc) \ 
475         (*(conn)->c_rdmamod->rdma_ops->rdma_regmemsync)(conn, adsp, buff, \ 
476             len, handle, synchandle, lrc) 
477  
478 #define RDMA_DEREGMEMSYNC(conn, buff, handle, synchandle, lrc)  \ 
479         (*(conn)->c_rdmamod->rdma_ops->rdma_deregmemsync)(conn, buff, \ 
480             handle, synchandle, lrc) 
481 #else 
482 #define RDMA_REGMEMSYNC(conn, adsp, buff, len, handle, synchandle)      \ 
483         (*(conn)->c_rdmamod->rdma_ops->rdma_regmemsync)(conn, adsp, buff, \ 
484             len, handle, synchandle)
485 
486 #define RDMA_DEREGMEMSYNC(conn, buff, handle, synchandle)       \
487         (*(conn)->c_rdmamod->rdma_ops->rdma_deregmemsync)(conn, buff, \
488             handle, synchandle)
489 
490 #endif
491 #define RDMA_SYNCMEM(conn, handle, buff, len, direction)        \
492         (*(conn)->c_rdmamod->rdma_ops->rdma_syncmem)(conn, handle, \
493             buff, len, direction)
494 
495 #define RDMA_BUF_ALLOC(conn, rbuf)      \
496         (*(conn)->c_rdmamod->rdma_ops->rdma_buf_alloc)(conn, rbuf)
497 
498 #define RDMA_BUF_FREE(conn, rbuf)       \
499         (*(conn)->c_rdmamod->rdma_ops->rdma_buf_free)(conn, rbuf)
500 
501 #define RDMA_SEND(conn, sendlist, xid)  \
502         (*(conn)->c_rdmamod->rdma_ops->rdma_send)(conn, sendlist, xid)
503 #if defined (CLNT_INTERRUPT_COAL)
504 #define RDMA_SEND_BL(conn, sendlist, xid)       \
505         (*(conn)->c_rdmamod->rdma_ops->rdma_send_bl)(conn, sendlist, xid)
506 
507 #endif
508 #if defined(ASYNC_SERVER_DEREG)
509 #define RDMA_SEND_NW(conn, sendlist, xid, c, c1, c2, c3, c4, c5, c6) \
510         (*(conn)->c_rdmamod->rdma_ops->rdma_send_nw)(conn, sendlist, xid, c, c1, c2, c3, c4, c5, c6)
511 #endif
512 #if defined(ASYNC_CLIENT_DEREG)
513 #define INSERT_QUEUE(conn,rwc)  \
514         (*(conn)->c_rdmamod->rdma_ops->insert_queue)(conn,rwc)
515 #endif
516 
517 #define RDMA_SEND_RESP(conn, sendlist, xid)     \
518         (*(conn)->c_rdmamod->rdma_ops->rdma_send_resp)(conn, sendlist, xid)
519 
520 #define RDMA_CLNT_RECVBUF(conn, cl, xid)        \
521         (*(conn)->c_rdmamod->rdma_ops->rdma_clnt_recvbuf)(conn, cl, xid)
522 
523 #define RDMA_SVC_RECVBUF(conn, cl)      \
524         (*(conn)->c_rdmamod->rdma_ops->rdma_svc_recvbuf)(conn, cl)
525 
526 #define RDMA_RECV(conn, recvlist, xid)  \
527         (*(conn)->c_rdmamod->rdma_ops->rdma_recv)(conn, recvlist, xid)
528 
529 #define RDMA_READ(conn, cl, wait)       \
530         (*(conn)->c_rdmamod->rdma_ops->rdma_read)(conn, cl, wait)
531 
532 #define RDMA_WRITE(conn, cl, wait)      \
533         (*(conn)->c_rdmamod->rdma_ops->rdma_write)(conn, cl, wait)
534 
535 #define RDMA_GETINFO(rdma_mod, info)    \
536         (*(rdma_mod)->rdma_ops->rdma_getinfo)(info)
537 
538 
539 #ifdef SERVER_REG_CACHE
540 #define RDMA_GET_SERVER_CACHE_BUF(conn, len)      \
541          (*(conn)->c_rdmamod->rdma_ops->rdma_get_server_cache_buf)(conn, len)
542 
543 #define RDMA_FREE_SERVER_CACHE_BUF(conn, buf)        \
544          (*(conn)->c_rdmamod->rdma_ops->rdma_free_server_cache_buf)(conn, buf)
545 #endif
546 
547 #ifdef DYNAMIC_CREDIT_CONTROL
548 #define RDMA_GET_RESOURCE_INFO(conn, num, avail)      \
549          (*(conn)->c_rdmamod->rdma_ops->rdma_get_resource_info)(conn, num, avail)
550 #endif
551 
552 #ifdef _KERNEL
553 extern rdma_registry_t  *rdma_mod_head;
554 extern krwlock_t rdma_lock;             /* protects rdma_mod_head list */
555 extern int rdma_modloaded;              /* flag for loading RDMA plugins */
556 extern int rdma_dev_available;          /* rdma device is loaded or not */
557 extern kmutex_t rdma_modload_lock;      /* protects rdma_modloaded flag */
558 extern uint_t rdma_minchunk;
559 extern ldi_ident_t rpcmod_li;           /* needed by layed driver framework */

560 /*
561  * General RDMA routines
562  */
563 extern void clist_add(struct clist **clp, uint32_t xdroff, int len,
564         struct mrc *shandle, caddr_t saddr,
565         struct mrc *dhandle, caddr_t daddr);
566 extern void clist_free(struct clist *cl);
567 extern int clist_register(CONN *conn, struct clist *cl, bool_t src);
568 extern int clist_deregister(CONN *conn, struct clist *cl, bool_t src);
569 rdma_stat rdma_clnt_postrecv(CONN *conn, uint32_t xid);
570 rdma_stat rdma_svc_postrecv(CONN *conn);
571 extern rdma_stat clist_syncmem(CONN *conn, struct clist *cl, bool_t src);
572 extern rdma_stat rdma_register_mod(rdma_mod_t *mod);
573 extern rdma_stat rdma_unregister_mod(rdma_mod_t *mod);
574 extern void rdma_buf_free(CONN *conn, rdma_buf_t *rbuf);
575 extern int rdma_modload();
576 
577 /*
578  * RDMA XDR
579  */
580 extern void xdrrdma_create(XDR *, caddr_t, uint_t, int, struct clist *,
581         enum xdr_op, CONN *);
582 extern void xdrrdma_destroy(XDR *);
583 extern struct clist *xdrrdma_clist(XDR *);
584 extern uint_t xdrrdma_getpos(XDR *);
585 extern bool_t xdrrdma_setpos(XDR *, uint_t);
586 extern bool_t xdr_clist(XDR *, clist *);
587 extern bool_t xdr_do_clist(XDR *, clist **);
588 extern uint_t xdr_getbufsize(XDR *);
589 unsigned int xdrrdma_sizeof(xdrproc_t func, void *data, int min_chunk);
590 unsigned int xdrrdma_authsize(AUTH *auth, struct cred *cred, int min_chunk);
591 
592 extern bool_t xdr_decode_reply_wchunk(XDR *, struct clist **,CONN *conn);
593 extern bool_t xdr_decode_wlist(XDR *xdrs, struct clist **, bool_t *);
594 extern bool_t xdr_decode_wlist_new(XDR *xdrs, struct clist **, bool_t *,
595         uint32_t *,CONN *);
596 
597 extern bool_t xdr_encode_wlist(XDR *, clist *, uint_t); 
598 extern bool_t xdr_encode_reply_wchunk(XDR *, struct clist *, uint32_t seg_array_len); 
599 
600 #endif /* _KERNEL */
601 
602 #ifdef __cplusplus
603 }
604 #endif
605 
606 #endif  /* _RPC_RPC_RDMA_H */
--- EOF ---