1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * xdr_rdma.c, XDR implementation using RDMA to move large chunks 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <sys/param.h> 34*0Sstevel@tonic-gate #include <sys/types.h> 35*0Sstevel@tonic-gate #include <sys/systm.h> 36*0Sstevel@tonic-gate #include <sys/kmem.h> 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate #include <rpc/types.h> 39*0Sstevel@tonic-gate #include <rpc/xdr.h> 40*0Sstevel@tonic-gate #include <sys/cmn_err.h> 41*0Sstevel@tonic-gate #include <rpc/rpc_sztypes.h> 42*0Sstevel@tonic-gate #include <rpc/rpc_rdma.h> 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate static struct xdr_ops *xdrrdma_ops(void); 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate /* 47*0Sstevel@tonic-gate * A chunk list entry identifies a chunk 48*0Sstevel@tonic-gate * of opaque data to be moved separately 49*0Sstevel@tonic-gate * from the rest of the RPC message. 50*0Sstevel@tonic-gate * xp_min_chunk = 0, is a special case for ENCODING, which means 51*0Sstevel@tonic-gate * do not chunk the incoming stream of data. 52*0Sstevel@tonic-gate */ 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate struct private { 55*0Sstevel@tonic-gate caddr_t xp_offp; 56*0Sstevel@tonic-gate int xp_min_chunk; 57*0Sstevel@tonic-gate uint_t xp_flags; /* Controls setting for rdma xdr */ 58*0Sstevel@tonic-gate int xp_buf_size; /* size of xdr buffer */ 59*0Sstevel@tonic-gate struct clist *xp_cl; /* head of chunk list */ 60*0Sstevel@tonic-gate struct clist **xp_cl_next; /* location to place/find next chunk */ 61*0Sstevel@tonic-gate CONN *xp_conn; /* connection for chunk data xfer */ 62*0Sstevel@tonic-gate }; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate /* 66*0Sstevel@tonic-gate * The procedure xdrrdma_create initializes a stream descriptor for a 67*0Sstevel@tonic-gate * memory buffer. 68*0Sstevel@tonic-gate */ 69*0Sstevel@tonic-gate void 70*0Sstevel@tonic-gate xdrrdma_create(XDR *xdrs, caddr_t addr, uint_t size, 71*0Sstevel@tonic-gate int min_chunk, struct clist *cl, enum xdr_op op, CONN *conn) 72*0Sstevel@tonic-gate { 73*0Sstevel@tonic-gate struct private *xdrp; 74*0Sstevel@tonic-gate struct clist *cle; 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate xdrs->x_op = op; 77*0Sstevel@tonic-gate xdrs->x_ops = xdrrdma_ops(); 78*0Sstevel@tonic-gate xdrs->x_base = addr; 79*0Sstevel@tonic-gate xdrs->x_handy = size; 80*0Sstevel@tonic-gate xdrs->x_public = NULL; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate xdrp = (struct private *)kmem_zalloc(sizeof (struct private), KM_SLEEP); 83*0Sstevel@tonic-gate xdrs->x_private = (caddr_t)xdrp; 84*0Sstevel@tonic-gate xdrp->xp_offp = addr; 85*0Sstevel@tonic-gate xdrp->xp_min_chunk = min_chunk; 86*0Sstevel@tonic-gate xdrp->xp_flags = 0; 87*0Sstevel@tonic-gate xdrp->xp_buf_size = size; 88*0Sstevel@tonic-gate xdrp->xp_cl = cl; 89*0Sstevel@tonic-gate if (op == XDR_ENCODE && cl != NULL) { 90*0Sstevel@tonic-gate /* Find last element in chunk list and set xp_cl_next */ 91*0Sstevel@tonic-gate for (cle = cl; cle->c_next != NULL; cle = cle->c_next); 92*0Sstevel@tonic-gate xdrp->xp_cl_next = &(cle->c_next); 93*0Sstevel@tonic-gate } else 94*0Sstevel@tonic-gate xdrp->xp_cl_next = &(xdrp->xp_cl); 95*0Sstevel@tonic-gate xdrp->xp_conn = conn; 96*0Sstevel@tonic-gate if (xdrp->xp_min_chunk == 0) 97*0Sstevel@tonic-gate xdrp->xp_flags |= RDMA_NOCHUNK; 98*0Sstevel@tonic-gate } 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate /* ARGSUSED */ 101*0Sstevel@tonic-gate void 102*0Sstevel@tonic-gate xdrrdma_destroy(XDR *xdrs) 103*0Sstevel@tonic-gate { 104*0Sstevel@tonic-gate (void) kmem_free(xdrs->x_private, sizeof (struct private)); 105*0Sstevel@tonic-gate } 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate struct clist * 108*0Sstevel@tonic-gate xdrrdma_clist(XDR *xdrs) { 109*0Sstevel@tonic-gate return (((struct private *)(xdrs->x_private))->xp_cl); 110*0Sstevel@tonic-gate } 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate static bool_t 113*0Sstevel@tonic-gate xdrrdma_getint32(XDR *xdrs, int32_t *int32p) 114*0Sstevel@tonic-gate { 115*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate if ((xdrs->x_handy -= (int)sizeof (int32_t)) < 0) 118*0Sstevel@tonic-gate return (FALSE); 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate /* LINTED pointer alignment */ 121*0Sstevel@tonic-gate *int32p = (int32_t)ntohl((uint32_t)(*((int32_t *)(xdrp->xp_offp)))); 122*0Sstevel@tonic-gate xdrp->xp_offp += sizeof (int32_t); 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate return (TRUE); 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate static bool_t 128*0Sstevel@tonic-gate xdrrdma_putint32(XDR *xdrs, int32_t *int32p) 129*0Sstevel@tonic-gate { 130*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate if ((xdrs->x_handy -= (int)sizeof (int32_t)) < 0) 133*0Sstevel@tonic-gate return (FALSE); 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate /* LINTED pointer alignment */ 136*0Sstevel@tonic-gate *(int32_t *)xdrp->xp_offp = (int32_t)htonl((uint32_t)(*int32p)); 137*0Sstevel@tonic-gate xdrp->xp_offp += sizeof (int32_t); 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate return (TRUE); 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate /* 143*0Sstevel@tonic-gate * DECODE some bytes from an XDR stream 144*0Sstevel@tonic-gate */ 145*0Sstevel@tonic-gate static bool_t 146*0Sstevel@tonic-gate xdrrdma_getbytes(XDR *xdrs, caddr_t addr, int len) 147*0Sstevel@tonic-gate { 148*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 149*0Sstevel@tonic-gate struct clist *cle = *(xdrp->xp_cl_next); 150*0Sstevel@tonic-gate struct clist cl; 151*0Sstevel@tonic-gate bool_t retval = TRUE; 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate /* 154*0Sstevel@tonic-gate * If there was a chunk at the current offset 155*0Sstevel@tonic-gate * first record the destination address and length 156*0Sstevel@tonic-gate * in the chunk list that came with the message, then 157*0Sstevel@tonic-gate * RDMA READ the chunk data. 158*0Sstevel@tonic-gate */ 159*0Sstevel@tonic-gate if (cle != NULL && 160*0Sstevel@tonic-gate cle->c_xdroff == (xdrp->xp_offp - xdrs->x_base)) { 161*0Sstevel@tonic-gate cle->c_daddr = (uint64)(uintptr_t)addr; 162*0Sstevel@tonic-gate cle->c_len = len; 163*0Sstevel@tonic-gate xdrp->xp_cl_next = &cle->c_next; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate /* 166*0Sstevel@tonic-gate * RDMA READ the chunk data from the remote end. 167*0Sstevel@tonic-gate * First prep the destination buffer by registering 168*0Sstevel@tonic-gate * it, then RDMA READ the chunk data. Since we are 169*0Sstevel@tonic-gate * doing streaming memory, sync the destination buffer 170*0Sstevel@tonic-gate * to CPU and deregister the buffer. 171*0Sstevel@tonic-gate */ 172*0Sstevel@tonic-gate if (xdrp->xp_conn == NULL) { 173*0Sstevel@tonic-gate return (FALSE); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate cl = *cle; 177*0Sstevel@tonic-gate cl.c_next = NULL; 178*0Sstevel@tonic-gate if (clist_register(xdrp->xp_conn, &cl, 0) != RDMA_SUCCESS) { 179*0Sstevel@tonic-gate return (FALSE); 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate /* 183*0Sstevel@tonic-gate * Now read the chunk in 184*0Sstevel@tonic-gate */ 185*0Sstevel@tonic-gate if (RDMA_READ(xdrp->xp_conn, &cl, WAIT) != RDMA_SUCCESS) { 186*0Sstevel@tonic-gate #ifdef DEBUG 187*0Sstevel@tonic-gate cmn_err(CE_WARN, 188*0Sstevel@tonic-gate "xdrrdma_getbytes: RDMA_READ failed\n"); 189*0Sstevel@tonic-gate #endif 190*0Sstevel@tonic-gate retval = FALSE; 191*0Sstevel@tonic-gate goto out; 192*0Sstevel@tonic-gate } 193*0Sstevel@tonic-gate /* 194*0Sstevel@tonic-gate * sync the memory for cpu 195*0Sstevel@tonic-gate */ 196*0Sstevel@tonic-gate if (clist_syncmem(xdrp->xp_conn, &cl, 0) != RDMA_SUCCESS) { 197*0Sstevel@tonic-gate retval = FALSE; 198*0Sstevel@tonic-gate goto out; 199*0Sstevel@tonic-gate } 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate out: 202*0Sstevel@tonic-gate /* 203*0Sstevel@tonic-gate * Deregister the chunks 204*0Sstevel@tonic-gate */ 205*0Sstevel@tonic-gate (void) clist_deregister(xdrp->xp_conn, &cl, 0); 206*0Sstevel@tonic-gate return (retval); 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate if ((xdrs->x_handy -= len) < 0) 210*0Sstevel@tonic-gate return (FALSE); 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate bcopy(xdrp->xp_offp, addr, len); 213*0Sstevel@tonic-gate xdrp->xp_offp += len; 214*0Sstevel@tonic-gate 215*0Sstevel@tonic-gate return (TRUE); 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate /* 219*0Sstevel@tonic-gate * ENCODE some bytes into an XDR stream 220*0Sstevel@tonic-gate * xp_min_chunk = 0, means the stream of bytes contain no chunks 221*0Sstevel@tonic-gate * to seperate out, and if the bytes do not fit in the supplied 222*0Sstevel@tonic-gate * buffer, grow the buffer and free the old buffer. 223*0Sstevel@tonic-gate */ 224*0Sstevel@tonic-gate static bool_t 225*0Sstevel@tonic-gate xdrrdma_putbytes(XDR *xdrs, caddr_t addr, int len) 226*0Sstevel@tonic-gate { 227*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 228*0Sstevel@tonic-gate struct clist *clzero = xdrp->xp_cl; 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate /* 231*0Sstevel@tonic-gate * If this chunk meets the minimum chunk size 232*0Sstevel@tonic-gate * then don't encode it. Just record its address 233*0Sstevel@tonic-gate * and length in a chunk list entry so that it 234*0Sstevel@tonic-gate * can be moved separately via RDMA. 235*0Sstevel@tonic-gate */ 236*0Sstevel@tonic-gate if (!(xdrp->xp_flags & RDMA_NOCHUNK) && xdrp->xp_min_chunk != 0 && 237*0Sstevel@tonic-gate len >= xdrp->xp_min_chunk) { 238*0Sstevel@tonic-gate struct clist *cle; 239*0Sstevel@tonic-gate int offset = xdrp->xp_offp - xdrs->x_base; 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate cle = (struct clist *)kmem_zalloc(sizeof (struct clist), 242*0Sstevel@tonic-gate KM_SLEEP); 243*0Sstevel@tonic-gate cle->c_xdroff = offset; 244*0Sstevel@tonic-gate cle->c_len = len; 245*0Sstevel@tonic-gate cle->c_saddr = (uint64)(uintptr_t)addr; 246*0Sstevel@tonic-gate cle->c_next = NULL; 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate *(xdrp->xp_cl_next) = cle; 249*0Sstevel@tonic-gate xdrp->xp_cl_next = &(cle->c_next); 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate return (TRUE); 252*0Sstevel@tonic-gate } 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate if ((xdrs->x_handy -= len) < 0) { 255*0Sstevel@tonic-gate if (xdrp->xp_min_chunk == 0) { 256*0Sstevel@tonic-gate int newbuflen, encodelen; 257*0Sstevel@tonic-gate caddr_t newbuf; 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate xdrs->x_handy += len; 260*0Sstevel@tonic-gate encodelen = xdrp->xp_offp - xdrs->x_base; 261*0Sstevel@tonic-gate newbuflen = xdrp->xp_buf_size + len; 262*0Sstevel@tonic-gate newbuf = kmem_zalloc(newbuflen, KM_SLEEP); 263*0Sstevel@tonic-gate bcopy(xdrs->x_base, newbuf, encodelen); 264*0Sstevel@tonic-gate (void) kmem_free(xdrs->x_base, xdrp->xp_buf_size); 265*0Sstevel@tonic-gate xdrs->x_base = newbuf; 266*0Sstevel@tonic-gate xdrp->xp_offp = newbuf + encodelen; 267*0Sstevel@tonic-gate xdrp->xp_buf_size = newbuflen; 268*0Sstevel@tonic-gate if (xdrp->xp_min_chunk == 0 && clzero->c_xdroff == 0) { 269*0Sstevel@tonic-gate clzero->c_len = newbuflen; 270*0Sstevel@tonic-gate clzero->c_saddr = (uint64)(uintptr_t)newbuf; 271*0Sstevel@tonic-gate } 272*0Sstevel@tonic-gate } else 273*0Sstevel@tonic-gate return (FALSE); 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate bcopy(addr, xdrp->xp_offp, len); 277*0Sstevel@tonic-gate xdrp->xp_offp += len; 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate return (TRUE); 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate uint_t 283*0Sstevel@tonic-gate xdrrdma_getpos(XDR *xdrs) 284*0Sstevel@tonic-gate { 285*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate return ((uint_t)((uintptr_t)xdrp->xp_offp - (uintptr_t)xdrs->x_base)); 288*0Sstevel@tonic-gate } 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate bool_t 291*0Sstevel@tonic-gate xdrrdma_setpos(XDR *xdrs, uint_t pos) 292*0Sstevel@tonic-gate { 293*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate caddr_t newaddr = xdrs->x_base + pos; 296*0Sstevel@tonic-gate caddr_t lastaddr = xdrp->xp_offp + xdrs->x_handy; 297*0Sstevel@tonic-gate ptrdiff_t diff; 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate if (newaddr > lastaddr) 300*0Sstevel@tonic-gate return (FALSE); 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate xdrp->xp_offp = newaddr; 303*0Sstevel@tonic-gate diff = lastaddr - newaddr; 304*0Sstevel@tonic-gate xdrs->x_handy = (int)diff; 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate return (TRUE); 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate /* ARGSUSED */ 310*0Sstevel@tonic-gate static rpc_inline_t * 311*0Sstevel@tonic-gate xdrrdma_inline(XDR *xdrs, int len) 312*0Sstevel@tonic-gate { 313*0Sstevel@tonic-gate rpc_inline_t *buf = NULL; 314*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 315*0Sstevel@tonic-gate struct clist *cle = *(xdrp->xp_cl_next); 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 318*0Sstevel@tonic-gate /* 319*0Sstevel@tonic-gate * Since chunks aren't in-line, check to see whether 320*0Sstevel@tonic-gate * there is a chunk in the inline range. 321*0Sstevel@tonic-gate */ 322*0Sstevel@tonic-gate if (cle != NULL && 323*0Sstevel@tonic-gate cle->c_xdroff <= (xdrp->xp_offp - xdrs->x_base + len)) 324*0Sstevel@tonic-gate return (NULL); 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate if ((xdrs->x_handy < len) || (xdrp->xp_min_chunk != 0 && 328*0Sstevel@tonic-gate len >= xdrp->xp_min_chunk)) { 329*0Sstevel@tonic-gate return (NULL); 330*0Sstevel@tonic-gate } else { 331*0Sstevel@tonic-gate xdrs->x_handy -= len; 332*0Sstevel@tonic-gate /* LINTED pointer alignment */ 333*0Sstevel@tonic-gate buf = (rpc_inline_t *)xdrp->xp_offp; 334*0Sstevel@tonic-gate xdrp->xp_offp += len; 335*0Sstevel@tonic-gate return (buf); 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate static bool_t 340*0Sstevel@tonic-gate xdrrdma_control(XDR *xdrs, int request, void *info) 341*0Sstevel@tonic-gate { 342*0Sstevel@tonic-gate int32_t *int32p; 343*0Sstevel@tonic-gate int len; 344*0Sstevel@tonic-gate uint_t in_flags; 345*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate switch (request) { 348*0Sstevel@tonic-gate case XDR_PEEK: 349*0Sstevel@tonic-gate /* 350*0Sstevel@tonic-gate * Return the next 4 byte unit in the XDR stream. 351*0Sstevel@tonic-gate */ 352*0Sstevel@tonic-gate if (xdrs->x_handy < sizeof (int32_t)) 353*0Sstevel@tonic-gate return (FALSE); 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate int32p = (int32_t *)info; 356*0Sstevel@tonic-gate *int32p = (int32_t)ntohl((uint32_t) 357*0Sstevel@tonic-gate (*((int32_t *)(xdrp->xp_offp)))); 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate return (TRUE); 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate case XDR_SKIPBYTES: 362*0Sstevel@tonic-gate /* 363*0Sstevel@tonic-gate * Skip the next N bytes in the XDR stream. 364*0Sstevel@tonic-gate */ 365*0Sstevel@tonic-gate int32p = (int32_t *)info; 366*0Sstevel@tonic-gate len = RNDUP((int)(*int32p)); 367*0Sstevel@tonic-gate if ((xdrs->x_handy -= len) < 0) 368*0Sstevel@tonic-gate return (FALSE); 369*0Sstevel@tonic-gate xdrp->xp_offp += len; 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate return (TRUE); 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate case XDR_RDMASET: 374*0Sstevel@tonic-gate /* 375*0Sstevel@tonic-gate * Set the flags provided in the *info in xp_flags for rdma xdr 376*0Sstevel@tonic-gate * stream control. 377*0Sstevel@tonic-gate */ 378*0Sstevel@tonic-gate int32p = (int32_t *)info; 379*0Sstevel@tonic-gate in_flags = (uint_t)(*int32p); 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate xdrp->xp_flags |= in_flags; 382*0Sstevel@tonic-gate return (TRUE); 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate case XDR_RDMAGET: 385*0Sstevel@tonic-gate /* 386*0Sstevel@tonic-gate * Get the flags provided in xp_flags return through *info 387*0Sstevel@tonic-gate */ 388*0Sstevel@tonic-gate int32p = (int32_t *)info; 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate *int32p = (int32_t)xdrp->xp_flags; 391*0Sstevel@tonic-gate return (TRUE); 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate default: 394*0Sstevel@tonic-gate return (FALSE); 395*0Sstevel@tonic-gate } 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gate static struct xdr_ops * 399*0Sstevel@tonic-gate xdrrdma_ops(void) 400*0Sstevel@tonic-gate { 401*0Sstevel@tonic-gate static struct xdr_ops ops; 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate if (ops.x_getint32 == NULL) { 404*0Sstevel@tonic-gate ops.x_getbytes = xdrrdma_getbytes; 405*0Sstevel@tonic-gate ops.x_putbytes = xdrrdma_putbytes; 406*0Sstevel@tonic-gate ops.x_getpostn = xdrrdma_getpos; 407*0Sstevel@tonic-gate ops.x_setpostn = xdrrdma_setpos; 408*0Sstevel@tonic-gate ops.x_inline = xdrrdma_inline; 409*0Sstevel@tonic-gate ops.x_destroy = xdrrdma_destroy; 410*0Sstevel@tonic-gate ops.x_control = xdrrdma_control; 411*0Sstevel@tonic-gate ops.x_getint32 = xdrrdma_getint32; 412*0Sstevel@tonic-gate ops.x_putint32 = xdrrdma_putint32; 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate return (&ops); 415*0Sstevel@tonic-gate } 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gate /* 418*0Sstevel@tonic-gate * Not all fields in struct clist are interesting to the 419*0Sstevel@tonic-gate * RPC over RDMA protocol. Only XDR the interesting fields. 420*0Sstevel@tonic-gate */ 421*0Sstevel@tonic-gate bool_t 422*0Sstevel@tonic-gate xdr_clist(XDR *xdrs, clist *objp) 423*0Sstevel@tonic-gate { 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate if (!xdr_uint32(xdrs, &objp->c_xdroff)) 426*0Sstevel@tonic-gate return (FALSE); 427*0Sstevel@tonic-gate if (!xdr_uint32(xdrs, &objp->c_len)) 428*0Sstevel@tonic-gate return (FALSE); 429*0Sstevel@tonic-gate if (!xdr_uint32(xdrs, &objp->c_smemhandle.mrc_rmr)) 430*0Sstevel@tonic-gate return (FALSE); 431*0Sstevel@tonic-gate if (!xdr_uint64(xdrs, &objp->c_saddr)) 432*0Sstevel@tonic-gate return (FALSE); 433*0Sstevel@tonic-gate if (!xdr_pointer(xdrs, (char **)&objp->c_next, sizeof (clist), 434*0Sstevel@tonic-gate (xdrproc_t)xdr_clist)) 435*0Sstevel@tonic-gate return (FALSE); 436*0Sstevel@tonic-gate return (TRUE); 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate bool_t 440*0Sstevel@tonic-gate xdr_do_clist(XDR *xdrs, clist **clp) 441*0Sstevel@tonic-gate { 442*0Sstevel@tonic-gate return (xdr_pointer(xdrs, (char **)clp, 443*0Sstevel@tonic-gate sizeof (clist), (xdrproc_t)xdr_clist)); 444*0Sstevel@tonic-gate } 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate uint_t 447*0Sstevel@tonic-gate xdr_getbufsize(XDR *xdrs) 448*0Sstevel@tonic-gate { 449*0Sstevel@tonic-gate struct private *xdrp = (struct private *)(xdrs->x_private); 450*0Sstevel@tonic-gate 451*0Sstevel@tonic-gate return ((uint_t)xdrp->xp_buf_size); 452*0Sstevel@tonic-gate } 453