[openib-general] [RFC][PATCH][REV2] uDAPL atomic extensions and immediate data changes

Arlin Davis arlin.r.davis at intel.com
Wed Jan 18 16:37:11 PST 2006


James,

 

Attached is a patch that includes immediate data as a standard API and atomics via extensions.
Changes have been made to the extensions based on discussions with Arkady (name changes and addition
of extended dat_return and memory privileges). This matches the DAT 2.0 extension proposal that I
sent out earlier.

 

-arlin

 

Signed-off by: Arlin Davis  <mailto:ardavis at ichips.intel.com> <ardavis at ichips.intel.com>

 

Index: test/dtest/dtest_ext.c
===================================================================
--- test/dtest/dtest_ext.c    (revision 0)
+++ test/dtest/dtest_ext.c    (revision 0)
@@ -0,0 +1,952 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <getopt.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#include "dat/udat.h"
+
+/*
+ * Map DAT_RETURN values to readable strings,
+ * but don't assume the values are zero-based or contiguous.
+ */
+char    errmsg[256] = {0};
+char majmsg[64] = {0};
+char minmsg[64] = {0};
+char extmsg[64] = {0};
+const char *
+DT_RetToString (DAT_RETURN ret_value)
+{
+    const char *major_msg = majmsg;
+    const char *minor_msg = minmsg;
+    const char *ext_msg = extmsg;
+    int sz;
+
+    /* DAT_NOT_IMPLEMENTED definition masked improperly in dat_error.h */
+    if (ret_value == DAT_NOT_IMPLEMENTED) {
+     strcpy(errmsg, "DAT_NOT_IMPLEMENTED");
+     return errmsg;
+    }
+
+    dat_strerror(ret_value, &major_msg, &minor_msg);
+    dat_strerror_extension(ret_value, &ext_msg);
+    strcpy(errmsg, major_msg);
+    strcat(errmsg, " ");
+    strcpy(errmsg, ext_msg);
+    strcat(errmsg, " ");
+    strcat(errmsg, minor_msg);
+
+    return errmsg;
+}
+
+/*
+ * Map DAT_EVENT_CODE values to readable strings
+ */
+const char *
+DT_EventToSTr (DAT_EVENT_NUMBER event_code)
+{
+    unsigned int i;
+    static struct {
+           const char  *name;
+           DAT_RETURN  value;
+    }
+    dat_events[] =
+    {
+           #   define DATxx(x) { # x, x }
+           DATxx (DAT_DTO_COMPLETION_EVENT),
+           DATxx (DAT_RMR_BIND_COMPLETION_EVENT),
+           DATxx (DAT_CONNECTION_REQUEST_EVENT),
+           DATxx (DAT_CONNECTION_EVENT_ESTABLISHED),
+           DATxx (DAT_CONNECTION_EVENT_PEER_REJECTED),
+           DATxx (DAT_CONNECTION_EVENT_NON_PEER_REJECTED),
+           DATxx (DAT_CONNECTION_EVENT_ACCEPT_COMPLETION_ERROR),
+           DATxx (DAT_CONNECTION_EVENT_DISCONNECTED),
+           DATxx (DAT_CONNECTION_EVENT_BROKEN),
+           DATxx (DAT_CONNECTION_EVENT_TIMED_OUT),
+           DATxx (DAT_CONNECTION_EVENT_UNREACHABLE),
+           DATxx (DAT_ASYNC_ERROR_EVD_OVERFLOW),
+           DATxx (DAT_ASYNC_ERROR_IA_CATASTROPHIC),
+           DATxx (DAT_ASYNC_ERROR_EP_BROKEN),
+           DATxx (DAT_ASYNC_ERROR_TIMED_OUT),
+           DATxx (DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR),
+           DATxx (DAT_SOFTWARE_EVENT)
+        #   undef DATxx
+    };
+    #   define NUM_EVENTS (sizeof(dat_events)/sizeof(dat_events[0]))
+
+    for (i = 0;  i < NUM_EVENTS;  i++) {
+           if (dat_events[i].value == event_code)
+           {
+               return ( dat_events[i].name );
+           }
+    }
+    return ( "Invalid_DAT_EVENT_NUMBER" );
+}
+
+/*
+ * Map DAT_EVENT_CODE values to readable strings
+ */
+const char *
+DT_DtoStatusToSTr (DAT_DTO_COMPLETION_STATUS dto_status )
+{
+    unsigned int i;
+    static struct {
+           const char  *name;
+           DAT_RETURN  value;
+    }
+    dat_dto[] =
+    {
+           #   define DATxx(x) { # x, x }
+           DATxx (DAT_DTO_SUCCESS),
+           DATxx (DAT_DTO_ERR_FLUSHED),
+           DATxx (DAT_DTO_ERR_LOCAL_LENGTH),
+           DATxx (DAT_DTO_ERR_LOCAL_EP),
+           DATxx (DAT_DTO_ERR_LOCAL_PROTECTION),
+           DATxx (DAT_DTO_ERR_BAD_RESPONSE),
+           DATxx (DAT_DTO_ERR_REMOTE_ACCESS),
+           DATxx (DAT_DTO_ERR_REMOTE_RESPONDER),
+           DATxx (DAT_DTO_ERR_TRANSPORT),
+           DATxx (DAT_DTO_ERR_RECEIVER_NOT_READY),
+           DATxx (DAT_DTO_ERR_PARTIAL_PACKET),
+           DATxx (DAT_RMR_OPERATION_FAILED)
+           #   undef DATxx
+    };
+    #   define NUM_DTO_ERRS (sizeof(dat_dto)/sizeof(dat_dto[0]))
+
+    for (i = 0;  i < NUM_DTO_ERRS;  i++) {
+           if (dat_dto[i].value == dto_status)
+           {
+               return ( dat_dto[i].name );
+           }
+    }
+    return ( "Invalid DAT_DTO_COMPLETION_STATUS" );
+}
+
+#define _OK( status, str ) \
+{ \
+     if ( status != DAT_SUCCESS ) { \
+           fprintf(stderr, str " returned %s\n", \
+                 DT_RetToString(status) ); \
+           exit ( 1 ); \
+     } \
+}
+
+#define _OK_EVENT( event, status, str ) \
+{ \
+     if ( status != DAT_SUCCESS ) { \
+           fprintf(stderr, str " event %s status %s\n", \
+                 DT_EventToSTr(event), DT_DtoStatusToSTr(status)); \
+           exit ( 1 ); \
+     } \
+}
+
+#define SECONDS( secs )      (1000*1000*secs)
+
+#define SERVER_CONN_QUAL     31111
+#define BUF_SIZE       256
+#define BUF_SIZE_ATOMIC            8
+#define REG_MEM_COUNT        10
+
+#define SND_RDMA_BUF_INDEX   0
+#define RCV_RDMA_BUF_INDEX   1
+#define SEND_BUF_INDEX       2
+#define RECV_BUF_INDEX       3
+
+u_int64_t        *atomic_buf;
+DAT_LMR_HANDLE         lmr_atomic;
+DAT_LMR_CONTEXT        lmr_atomic_context;
+DAT_RMR_CONTEXT        rmr_atomic_context;
+DAT_VLEN         reg_atomic_size;
+DAT_VADDR        reg_atomic_addr;
+
+DAT_LMR_HANDLE         lmr[ REG_MEM_COUNT ];
+DAT_LMR_CONTEXT        lmr_context[ REG_MEM_COUNT ];
+DAT_RMR_TRIPLET        rmr[ REG_MEM_COUNT ];
+DAT_RMR_CONTEXT        rmr_context[ REG_MEM_COUNT ];
+DAT_VLEN         reg_size[ REG_MEM_COUNT ];
+DAT_VADDR        reg_addr[ REG_MEM_COUNT ];
+DAT_RMR_TRIPLET *      buf[ REG_MEM_COUNT ];
+DAT_EP_HANDLE          ep;
+DAT_EVD_HANDLE         async_evd = DAT_HANDLE_NULL;
+DAT_IA_HANDLE          ia = DAT_HANDLE_NULL;
+DAT_PZ_HANDLE          pz = DAT_HANDLE_NULL;
+DAT_EVD_HANDLE         cr_evd = DAT_HANDLE_NULL;
+DAT_EVD_HANDLE         con_evd = DAT_HANDLE_NULL;
+DAT_EVD_HANDLE         dto_evd = DAT_HANDLE_NULL;
+DAT_PSP_HANDLE         psp = DAT_HANDLE_NULL;
+DAT_CR_HANDLE          cr = DAT_HANDLE_NULL;
+int              server = 1;
+
+void
+send_msg(
+     void *data,
+     DAT_COUNT size,
+     DAT_LMR_CONTEXT context,
+     DAT_DTO_COOKIE cookie,
+     DAT_COMPLETION_FLAGS flags )
+{
+     DAT_LMR_TRIPLET               iov;
+     DAT_EVENT               event;
+     DAT_COUNT               nmore;
+     DAT_RETURN              status;
+
+     iov.lmr_context     = context;
+     iov.pad             = 0;
+     iov.virtual_address = (DAT_VADDR)(unsigned long)data;
+     iov.segment_length  = (DAT_VLEN)size;
+
+     status = dat_ep_post_send( ep,
+                          1,
+                          &iov,
+                          cookie,
+                          flags );
+     _OK( status, "dat_ep_post_send" );
+
+     if ( ! (flags & DAT_COMPLETION_SUPPRESS_FLAG) ) {
+           status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+           _OK( status, "dat_evd_wait after dat_ep_post_send" );
+
+           if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+                 printf("unexpected event waiting for post_send completion - 0x%x\n",
event.event_number);
+                 exit ( 1 );
+           }
+
+           _OK( event.event_data.dto_completion_event_data.status, "event status for post_send" );
+     }
+}
+
+int
+connect_ep( char *hostname )
+{
+     DAT_SOCK_ADDR           remote_addr;
+     DAT_EP_ATTR       ep_attr;
+     DAT_RETURN        status;
+     DAT_REGION_DESCRIPTION  region;
+     DAT_EVENT         event;
+     DAT_COUNT         nmore;
+     DAT_LMR_TRIPLET         iov;
+     DAT_RMR_TRIPLET         r_iov;
+     DAT_DTO_COOKIE          cookie;
+     DAT_PROVIDER_ATTR provider_attr;
+     DAT_NAMED_ATTR          named_attrs; 
+     int               i,ext_cnt;
+     DAT_DTO_COMPLETION_EVENT_DATA *dto_event = &event.event_data.dto_completion_event_data;
+
+     status = dat_ia_open( "OpenIB-ib0", 8, &async_evd, &ia );
+     _OK( status, "dat_ia_open" );
+
+     /* query for immediate data and atomic operation extensions */
+     status = dat_ia_query( ia, NULL, DAT_IA_FIELD_NONE, NULL,
+                        DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR,
+                        &provider_attr );
+     _OK( status, "dat_ia_query" );
+
+     /* look for extension support, ALL or nothing */
+     ext_cnt=0;
+     printf(" Extension Attributes:\n");
+     for (i=0;i<provider_attr.num_provider_specific_attr;i++) {
+           /* check extension version */
+           if ((!strcmp(provider_attr.provider_specific_attr[i].name,
+                      DAT_EXTENSION_ATTR_VERSION))) {
+               printf(" %s = %s\n",
+                     provider_attr.provider_specific_attr[i].name,
+                     provider_attr.provider_specific_attr[i].value);
+               if (!strcmp(provider_attr.provider_specific_attr[i].value, 
+                 DAT_EXTENSION_ATTR_VERSION_VALUE)) {
+                       ext_cnt++;  
+                       continue;
+               } else 
+                     break;
+           } 
+           /* check extension names set to TRUE */
+           if ((!strcmp(provider_attr.provider_specific_attr[i].name, 
+                       DAT_EXTENSION_ATTR)) ||
+               (!strcmp(provider_attr.provider_specific_attr[i].name,
+                       DAT_EXTENSION_ATTR_FETCH_AND_ADD)) ||
+               (!strcmp(provider_attr.provider_specific_attr[i].name,
+                       DAT_EXTENSION_ATTR_CMP_AND_SWAP)) ) {
+               printf(" %s = %s\n",
+                    provider_attr.provider_specific_attr[i].name,
+                    provider_attr.provider_specific_attr[i].value);
+               if (strcmp(provider_attr.provider_specific_attr[i].value, 
+                       DAT_EXTENSION_ATTR_TRUE)) {
+                 break;
+               } else 
+                 ext_cnt++;
+           } else { 
+                 printf(" Extension Attribute: %s unknown\n",
+                       provider_attr.provider_specific_attr[i].name);
+                 continue;
+           }
+     }
+     /* all or nothing */
+     if (ext_cnt != 4) {
+           _OK( DAT_INVALID_HANDLE, "provider attr checking" );
+     }
+
+     status = dat_pz_create( ia, &pz );
+     _OK( status, "dat_pz_create" );
+
+     status = dat_evd_create( ia, 10, DAT_HANDLE_NULL, DAT_EVD_CR_FLAG, &cr_evd  );
+     _OK( status, "dat_evd_create CR" );
+     status = dat_evd_create( ia, 10, DAT_HANDLE_NULL, DAT_EVD_CONNECTION_FLAG, &con_evd  );
+     _OK( status, "dat_evd_create CR" );
+     status = dat_evd_create( ia, 10, DAT_HANDLE_NULL, DAT_EVD_DTO_FLAG, &dto_evd  );
+     _OK( status, "dat_evd_create DTO" );
+
+     memset( &ep_attr, 0, sizeof(ep_attr) );
+     ep_attr.service_type                = DAT_SERVICE_TYPE_RC;
+     ep_attr.max_rdma_size               = 0x10000;
+     ep_attr.qos                         = 0;
+     ep_attr.recv_completion_flags       = 0;
+     ep_attr.max_recv_dtos               = 10;
+     ep_attr.max_request_dtos            = 10;
+     ep_attr.max_recv_iov                = 1;
+     ep_attr.max_request_iov             = 1;
+     ep_attr.max_rdma_read_in            = 4;
+     ep_attr.max_rdma_read_out           = 4;
+     ep_attr.request_completion_flags    = DAT_COMPLETION_DEFAULT_FLAG;
+     ep_attr.ep_transport_specific_count = 0;
+     ep_attr.ep_transport_specific       = NULL;
+     ep_attr.ep_provider_specific_count  = 0;
+     ep_attr.ep_provider_specific        = NULL;
+
+     status = dat_ep_create( ia, pz, dto_evd, dto_evd, con_evd, &ep_attr, &ep );
+     _OK( status, "dat_ep_create" );
+
+     for ( i = 0; i < REG_MEM_COUNT; i++ ) {
+           buf[ i ] = (DAT_RMR_TRIPLET*)malloc( BUF_SIZE );
+           region.for_va = buf[ i ];
+           status = dat_lmr_create( ia,
+                             DAT_MEM_TYPE_VIRTUAL,
+                             region,
+                             BUF_SIZE,
+                             pz,
+                             DAT_MEM_PRIV_ALL_FLAG | DAT_MEM_PRIV_EXT_REMOTE_ATOMIC,
+                             &lmr[ i ],
+                             &lmr_context[ i ],
+                             &rmr_context[ i ],
+                             &reg_size[ i ],
+                             &reg_addr[ i ] );
+           _OK( status, "dat_lmr_create" );
+#if 0
+           printf(" buf[%d]=%p, reg_addr[%d]=%p\n",
+                 i, buf[ i ], i, reg_addr[ i ]);
+#endif
+     }
+
+     printf(" PRIV_REMOTE_ATOMIC = 0x%x all=0x%x\n", 
+           DAT_MEM_PRIV_EXT_REMOTE_ATOMIC,
+           DAT_MEM_PRIV_ALL_FLAG );
+
+     /* register atomic return buffer for original data */
+     atomic_buf = (u_int64_t*)malloc( BUF_SIZE );
+     region.for_va = atomic_buf;
+     status = dat_lmr_create( ia,
+                       DAT_MEM_TYPE_VIRTUAL,
+                       region,
+                       BUF_SIZE_ATOMIC,
+                       pz,
+                       //DAT_MEM_PRIV_ALL_FLAG,
+                       DAT_MEM_PRIV_ALL_FLAG | DAT_MEM_PRIV_EXT_REMOTE_ATOMIC,
+                       &lmr_atomic,
+                       &lmr_atomic_context,
+                       &rmr_atomic_context,
+                       &reg_atomic_size,
+                       &reg_atomic_addr );
+     _OK( status, "dat_lmr_create atomic" );
+     
+     for ( i = RECV_BUF_INDEX; i < REG_MEM_COUNT; i++ ) {
+           cookie.as_64        = i;
+           iov.lmr_context     = lmr_context[ i ];
+           iov.pad             = 0;
+           iov.virtual_address = (DAT_VADDR)(unsigned long)buf[ i ];
+           iov.segment_length  = BUF_SIZE;
+
+           status = dat_ep_post_recv_immed(ep,
+                                   1,
+                                   &iov,
+                                   cookie,
+                                   DAT_COMPLETION_DEFAULT_FLAG );
+           _OK( status, "dat_ep_post_recv_immed" );
+     }
+
+     /* setup receive buffer to initial string to be overwritten */
+     strcpy( (char*)buf[ RCV_RDMA_BUF_INDEX ], "blah, blah, blah\n" );
+
+     if ( server ) {
+
+           strcpy( (char*)buf[ SND_RDMA_BUF_INDEX ], "server written data" );
+
+           status = dat_psp_create( ia,
+                             SERVER_CONN_QUAL,
+                             cr_evd,
+                             DAT_PSP_CONSUMER_FLAG,
+                             &psp );
+           _OK( status, "dat_psp_create" );
+
+           printf("Server waiting for connect request\n");
+           status = dat_evd_wait( cr_evd, SECONDS( 20 ), 1, &event, &nmore );
+           _OK( status, "listen dat_evd_wait" );
+
+           if ( event.event_number != DAT_CONNECTION_REQUEST_EVENT ) {
+                 printf("unexpected event after dat_psp_create: 0x%x\n", event.event_number); 
+                 exit ( 1 );
+           }
+
+           if ( (event.event_data.cr_arrival_event_data.conn_qual != SERVER_CONN_QUAL) ||
+                (event.event_data.cr_arrival_event_data.sp_handle.psp_handle != psp) ) {
+
+                 printf("wrong cr event data\n");
+                 exit ( 1 );
+           }
+
+           cr = event.event_data.cr_arrival_event_data.cr_handle;
+           status = dat_cr_accept( cr, ep, 0, (DAT_PVOID)0 );
+
+     } else {
+           struct addrinfo   *target;
+           int rval;
+
+           if (getaddrinfo (hostname, NULL, NULL, &target) != 0) {
+                 printf("Error getting remote address.\n");
+                 exit ( 1 );
+           }
+
+           rval = ((struct sockaddr_in *)target->ai_addr)->sin_addr.s_addr;
+           printf ("Server Name: %s \n", hostname);
+           printf ("Server Net Address: %d.%d.%d.%d\n",
+               (rval >>  0) & 0xff,
+               (rval >>  8) & 0xff,
+               (rval >> 16) & 0xff,
+               (rval >> 24) & 0xff);
+
+           remote_addr = *((DAT_IA_ADDRESS_PTR)target->ai_addr);
+
+           strcpy( (char*)buf[ SND_RDMA_BUF_INDEX ], "client written data" );
+
+           status = dat_ep_connect( ep,
+                             &remote_addr,
+                             SERVER_CONN_QUAL,
+                             SECONDS( 20 ),
+                             0,
+                             (DAT_PVOID)0,
+                             0,
+                             DAT_CONNECT_DEFAULT_FLAG  );
+           _OK( status, "dat_psp_create" );
+
+           
+     }
+
+     printf("Client waiting for connect response\n");
+     status = dat_evd_wait( con_evd, SECONDS( 5 ), 1, &event, &nmore );
+     _OK( status, "connect dat_evd_wait" );
+
+     if ( event.event_number != DAT_CONNECTION_EVENT_ESTABLISHED ) {
+           printf("unexpected event after dat_ep_connect: 0x%x\n", event.event_number); 
+           exit ( 1 );
+     }
+
+     printf("Connected!\n");
+
+     /*
+     *  Setup our remote memory and tell the other side about it
+     */
+     printf("Sending RMR data to remote\n");
+     r_iov.rmr_context    = rmr_context[ RCV_RDMA_BUF_INDEX ];
+     r_iov.pad        = 0;
+     r_iov.target_address = (DAT_VADDR)((unsigned long)buf[ RCV_RDMA_BUF_INDEX ]);
+     r_iov.segment_length = BUF_SIZE;
+
+     *buf[ SEND_BUF_INDEX ] = r_iov;
+
+     send_msg(buf[ SEND_BUF_INDEX ],
+           sizeof( DAT_RMR_TRIPLET ),
+           lmr_context[ SEND_BUF_INDEX ],
+           cookie,
+           DAT_COMPLETION_SUPPRESS_FLAG );
+
+     /*
+     *  Wait for their RMR
+     */
+     printf("Waiting for remote to send RMR data\n");
+     status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+     _OK( status, "dat_evd_wait after dat_ep_post_send" );
+
+     if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+           printf("unexpected event waiting for RMR context - 0x%x\n", 
+                 event.event_number);
+           exit ( 1 );
+     }
+
+     _OK_EVENT( event.event_number, dto_event->status, " post_send" );
+     if ( (dto_event->transfered_length != sizeof( DAT_RMR_TRIPLET )) ||
+          (dto_event->user_cookie.as_64 != RECV_BUF_INDEX) ) {
+           printf("unexpected event data for receive: len=%d cookie=%d expected %d/%d\n",
+                 (int)dto_event->transfered_length,
+                 (int)dto_event->user_cookie.as_64,
+                 sizeof(DAT_RMR_TRIPLET), RECV_BUF_INDEX);
+           exit ( 1 );
+     }
+
+     r_iov = *buf[ RECV_BUF_INDEX ];
+
+     printf("Received RMR from remote: r_iov: ctx=%x,pad=%x,va=%p,len=%d\n",
+           r_iov.rmr_context,
+           r_iov.pad,
+           (void*)(unsigned long)r_iov.target_address,
+           r_iov.segment_length );
+
+     return ( 0 );
+}
+
+int
+disconnect_ep( )
+{
+     DAT_RETURN  status;
+     int               i;
+
+     status = dat_ep_disconnect( ep, DAT_CLOSE_DEFAULT );
+     _OK( status, "dat_ep_disconnect" );
+
+     printf("EP disconnected\n");
+
+     if ( server ) {
+           status = dat_psp_free( psp );
+           _OK( status, "dat_ep_disconnect" );
+     }
+
+     for ( i = 0; i < REG_MEM_COUNT; i++ ) {
+           status = dat_lmr_free( lmr[ i ] );
+           _OK( status, "dat_lmr_free" );
+     }
+
+     status = dat_lmr_free( lmr_atomic );
+     _OK( status, "dat_lmr_free_atomic" );
+
+     status = dat_ep_free( ep );
+     _OK( status, "dat_ep_free" );
+
+     status = dat_evd_free( dto_evd );
+     _OK( status, "dat_evd_free DTO" );
+     status = dat_evd_free( con_evd );
+     _OK( status, "dat_evd_free CON" );
+     status = dat_evd_free( cr_evd );
+     _OK( status, "dat_evd_free CR" );
+
+     status = dat_pz_free( pz );
+     _OK( status, "dat_pz_free" );
+
+     status = dat_ia_close( ia, DAT_CLOSE_DEFAULT );
+     _OK( status, "dat_ia_close" );
+
+     return ( 0 );
+}
+
+int
+do_immediate( )
+{
+     DAT_REGION_DESCRIPTION  region;
+     DAT_EVENT         event;
+     DAT_COUNT         nmore;
+     DAT_LMR_TRIPLET         iov;
+     DAT_RMR_TRIPLET         r_iov;
+     DAT_DTO_COOKIE          cookie;
+     DAT_RMR_CONTEXT         their_context;
+     DAT_RETURN        status;
+     DAT_UINT32        immed_data;
+     DAT_UINT32        immed_data_recv;
+     DAT_DTO_COMPLETION_EVENT_DATA *dto_event = 
+                       &event.event_data.dto_completion_event_data;
+
+     printf("\nDoing RDMA WRITE IMMEDIATE DATA\n");
+
+     if ( server ) {
+           immed_data = 0x1111;
+     } else {
+           immed_data = 0x7777;
+     }
+
+     cookie.as_64 = 0x5555;
+     
+     r_iov = *buf[ RECV_BUF_INDEX ];
+
+     iov.lmr_context     = lmr_context[ SND_RDMA_BUF_INDEX ];
+     iov.pad             = 0;
+     iov.virtual_address = (DAT_VADDR)(unsigned long)buf[ SND_RDMA_BUF_INDEX ];
+     iov.segment_length  = BUF_SIZE;
+
+     cookie.as_64 = 0x9999;
+     
+     status = dat_ep_post_rdma_write_immed( ep,            // ep_handle
+                                   1,          // num_segments
+                                   &iov,       // LMR
+                                   cookie,           // user_cookie
+                                   &r_iov,           // RMR
+                                   immed_data,
+                                   DAT_DTO_IMMED_FLAG,
+                                   DAT_COMPLETION_DEFAULT_FLAG );
+
+     _OK( status, "dat_ep_post_rdma_write_immed" );
+     printf("dat_ep_post_rdma_write_immed posted\n");
+
+     /*
+     *  Collect first event, write completion or the inbound rdma with immed
+     */
+     status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+     _OK( status, "dat_evd_wait after dat_ep_post_rdma_write" );
+     if ( event.event_number != DAT_DTO_COMPLETION_EVENT )
+     {
+           printf("unexpected event waiting for RMR context - 0x%x\n", 
+                 event.event_number );
+           exit ( 1 );
+     }
+     
+     _OK_EVENT( event.event_number, dto_event->status, " rdma_write_immed" );
+     if (dto_event->operation == DAT_RDMA_WRITE_IMMED )
+     {
+       if ((dto_event->transfered_length != BUF_SIZE) ||
+           (dto_event->user_cookie.as_64 != 0x9999) ) 
+       {
+              printf("unexpected event data for rdma_write_immed: len=%d cookie=0x%x\n",
+                 (int)dto_event->transfered_length,
+                 (int)dto_event->user_cookie.as_64);
+           exit ( 1 );
+       }
+     } 
+     else if (dto_event->operation == DAT_RECEIVE_RDMA_IMMED )
+        {
+       if ((dto_event->transfered_length != BUF_SIZE) ||
+           (dto_event->user_cookie.as_64 != RECV_BUF_INDEX+1))  {
+           printf("unexpected event data of immediate write:"
+                 "len=%d cookie=%d expected %d/%d\n",
+                 (int)dto_event->transfered_length,
+                 (int)dto_event->user_cookie.as_64,
+                 sizeof(int), RECV_BUF_INDEX+1);
+           exit ( 1 );
+       }
+       /* get immediate data from DTO event */
+       immed_data_recv = dto_event->immed_data;
+     }
+     else
+     {
+           printf("unexpected operation type - 0x%x, 0x%x\n", 
+                 event.event_number, dto_event->operation);
+           exit ( 1 );
+     }
+
+     /*
+     *  Collect second event, write completion or the inbound rdma with immed
+     */
+     status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+     _OK( status, "dat_evd_wait after dat_ep_post_rdma_write" );
+     if ( event.event_number != DAT_DTO_COMPLETION_EVENT )
+     {
+           printf("unexpected event waiting for RMR context - 0x%x\n", 
+                 event.event_number  );
+           exit ( 1 );
+     }
+     
+     _OK_EVENT( event.event_number, dto_event->status, " rdma_write_immed" );
+     if (dto_event->operation == DAT_RDMA_WRITE_IMMED )
+     {
+       if ((dto_event->transfered_length != BUF_SIZE) ||
+           (dto_event->user_cookie.as_64 != 0x9999) ) 
+       {
+              printf("unexpected event data for rdma_write_immed: len=%d cookie=0x%x\n",
+                 (int)dto_event->transfered_length,
+                 (int)dto_event->user_cookie.as_64);
+           exit ( 1 );
+       }
+     } 
+     else if (dto_event->operation == DAT_RECEIVE_RDMA_IMMED )
+        {
+       if ((dto_event->transfered_length != BUF_SIZE) ||
+           (dto_event->user_cookie.as_64 != RECV_BUF_INDEX+1))  {
+           printf("unexpected event data of immediate write:"
+                 "len=%d cookie=%d expected %d/%d\n",
+                 (int)dto_event->transfered_length,
+                 (int)dto_event->user_cookie.as_64,
+                 sizeof(int), RECV_BUF_INDEX+1);
+           exit ( 1 );
+       }
+       /* get immediate data from DTO event */
+       immed_data_recv = dto_event->immed_data;
+     }
+     else
+     {
+           printf("unexpected operation type - 0x%x, 0x%x\n", 
+                 event.event_number, dto_event->operation);
+           exit ( 1 );
+     }
+           
+     if ((server) && (immed_data_recv != 0x7777))
+     {
+           printf("Server got unexpected immed_data_recv 0x%x/0x%x\n", 
+                 0x7777,  immed_data_recv );
+           exit ( 1 );
+     } 
+     else if ((!server) && (immed_data_recv != 0x1111))
+     {
+           printf("Client got unexpected immed_data_recv 0x%x/0x%x\n", 
+                 0x1111,  immed_data_recv );
+           exit ( 1 );
+     }
+
+     if (server)
+         printf("Server received immed_data=0x%x, expected 0x7777\n", immed_data_recv );
+     else
+         printf("Client received immed_data=0x%x, expected 0x1111\n", immed_data_recv );
+     
+     printf("RCV buffer %p contains: %s\n", 
+           buf[ RCV_RDMA_BUF_INDEX ], buf[ RCV_RDMA_BUF_INDEX ]);
+
+     return ( 0 );
+}
+
+int
+do_cmp_swap()
+{
+     DAT_DTO_COOKIE    cookie;
+     DAT_RETURN        status;
+     DAT_EVENT         event;
+     DAT_COUNT         nmore;
+     DAT_LMR_TRIPLET         l_iov;
+     DAT_RMR_TRIPLET         r_iov;
+     volatile DAT_UINT64     *target = (DAT_UINT64*)buf[ RCV_RDMA_BUF_INDEX ];
+     DAT_DTO_COMPLETION_EVENT_DATA *dto_event = 
+                 &event.event_data.dto_completion_event_data;
+
+     printf("\nDoing CMP and SWAP\n");
+        
+     r_iov = *buf[ RECV_BUF_INDEX ];
+     
+     l_iov.lmr_context     = lmr_atomic_context;
+     l_iov.pad             = 0;
+     l_iov.virtual_address = (DAT_VADDR)(unsigned long)atomic_buf;
+     l_iov.segment_length  = BUF_SIZE_ATOMIC;
+
+     cookie.as_64 = 3333;
+     if ( server ) {
+           *target = 0x12345;
+           sleep(1);
+           /* server does not compare and should not swap */
+           status = dat_ep_post_cmp_and_swap(  ep, 
+                                         (DAT_UINT64)0x654321, 
+                                         (DAT_UINT64)0x6789A, 
+                                         &l_iov,
+                                         cookie, 
+                                         &r_iov, 
+                                         DAT_COMPLETION_DEFAULT_FLAG);
+     } else {
+           *target = 0x54321;
+           sleep(1);
+           /* client does compare and should swap */
+           status = dat_ep_post_cmp_and_swap(  ep, 
+                                         (DAT_UINT64)0x12345, 
+                                         (DAT_UINT64)0x98765,
+                                         &l_iov,
+                                         cookie, 
+                                         &r_iov, 
+                                         DAT_COMPLETION_DEFAULT_FLAG);
+     }
+     _OK( status, "dat_ep_post_cmp_and_swap" );
+     printf("dat_ep_post_cmp_and_swap posted\n");
+
+     status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+     _OK( status, "dat_evd_wait for compare and swap" );
+     if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+         printf("unexpected event after post_cmp_and_swap: 0x%x\n", 
+               event.event_number); 
+         exit ( 1 );
+     }
+
+     _OK_EVENT( event.event_number, dto_event->status, " cmp_swap" );
+     if ( dto_event->extension.type != DAT_DTO_EXTENSION_CMP_AND_SWAP ) {
+         printf("unexpected event data of cmp and swap : type=%d cookie=%d original 0x%llx\n",
+           (int)dto_event->extension.type,
+           (int)dto_event->user_cookie.as_64,
+           *atomic_buf);
+           exit ( 1 );
+     }
+     sleep(1);
+     if ( server ) {
+         printf("Server got original data        = 0x%llx, expected 0x54321\n", *atomic_buf);
+         printf("Client final result (on server) = 0x%llx, expected 0x98765\n", *target);
+     } else {
+         printf("Client got original data        = 0x%llx, expected 0x12345\n",*atomic_buf);
+         printf("Server final result (on client) = 0x%llx, expected 0x54321\n", *target);
+     }
+     return(0);
+}
+
+int
+do_fetch_add()
+{
+     DAT_DTO_COOKIE    cookie;
+     DAT_RETURN        status;
+     DAT_EVENT         event;
+     DAT_COUNT         nmore;
+     DAT_LMR_TRIPLET         l_iov;
+     DAT_RMR_TRIPLET         r_iov;
+     volatile DAT_UINT64     *target = (DAT_UINT64*)buf[ RCV_RDMA_BUF_INDEX ];
+     DAT_DTO_COMPLETION_EVENT_DATA *dto_event = 
+                 &event.event_data.dto_completion_event_data;
+
+     printf("\nDoing FETCH and ADD\n");
+
+     r_iov = *buf[ RECV_BUF_INDEX ];
+     
+     l_iov.lmr_context     = lmr_atomic_context;
+     l_iov.pad             = 0;
+     l_iov.virtual_address = (DAT_VADDR)(unsigned long)atomic_buf;
+     l_iov.segment_length  = BUF_SIZE_ATOMIC;
+
+     cookie.as_64 = 0x7777;
+     if ( server ) {
+           *target = 0x10;
+           sleep( 1 );
+           status = dat_ep_post_fetch_and_add( ep, 
+                                         (DAT_UINT64)0x100,
+                                         &l_iov,
+                                         cookie, 
+                                         &r_iov, 
+                                         DAT_COMPLETION_DEFAULT_FLAG);
+     } else {
+           *target = 0x100;
+           sleep( 1 );
+           status = dat_ep_post_fetch_and_add( ep, 
+                                         (DAT_UINT64)0x10, 
+                                         &l_iov,
+                                         cookie, 
+                                         &r_iov, 
+                                         DAT_COMPLETION_DEFAULT_FLAG);
+     }
+     _OK( status, "dat_ep_post_fetch_and_add" );
+     printf("dat_ep_post_fetch_and_add posted\n");
+     status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+     _OK( status, "dat_evd_wait for fetch and add" );
+     if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+           printf("unexpected event after post_fetch_and_add: 0x%x\n", event.event_number); 
+           exit ( 1 );
+     }
+
+     _OK_EVENT( event.event_number, dto_event->status, " fetch_add" );
+     if ( dto_event->extension.type != DAT_DTO_EXTENSION_FETCH_AND_ADD ) {
+           printf("unexpected event data of fetch and add : type=%d cookie=%d original%d\n",
+                 (int)dto_event->extension.type,
+                 (int)dto_event->user_cookie.as_64,
+                 (int)*atomic_buf );
+           exit ( 1 );
+     }
+
+     if ( server ) {
+         printf("Client original data (on server) = 0x%llx, expected 0x100\n", *atomic_buf );
+     } else {
+         printf("Server original data (on client) = 0x%llx, expected 0x10\n", *atomic_buf );
+     }
+
+     sleep( 1 ); 
+
+     if ( server ) {
+           status = dat_ep_post_fetch_and_add( ep, 
+                                         (DAT_UINT64)0x100, 
+                                         &l_iov,
+                                         cookie, 
+                                         &r_iov, 
+                                         DAT_COMPLETION_DEFAULT_FLAG);
+     } else {
+           status = dat_ep_post_fetch_and_add( ep, 
+                                         (DAT_UINT64)0x10,
+                                         &l_iov,
+                                         cookie, 
+                                         &r_iov, 
+                                         DAT_COMPLETION_DEFAULT_FLAG);
+     }
+
+     status = dat_evd_wait( dto_evd, SECONDS( 3 ), 1, &event, &nmore );
+     _OK( status, "dat_evd_wait for second fetch and add" );
+     if ( event.event_number != DAT_DTO_COMPLETION_EVENT ) {
+           printf("unexpected event after second post_fetch_and_add: 0x%x\n", event.event_number); 
+           exit ( 1 );
+     }
+
+     _OK_EVENT( event.event_number, dto_event->status, " fetch_add" );
+     if ( dto_event->extension.type != DAT_DTO_EXTENSION_FETCH_AND_ADD ) {
+           printf("unexpected event data of second fetch and add : type=%d cookie=%d original%d\n",
+                 (int)dto_event->extension.type,
+                 (int)dto_event->user_cookie.as_64,
+                 (long)atomic_buf);
+           exit ( 1 );
+     }
+
+     sleep( 1 );
+     if ( server ) {
+         printf("Server got original data         = 0x%llx, expected 0x200\n", *atomic_buf);
+         printf("Client final result (on server)  = 0x%llx, expected 0x30\n", *target);
+     } else {
+         printf("Server side original data        = 0x%llx, expected 0x20\n", *atomic_buf);
+         printf("Server final result (on client)  = 0x%llx, expected 0x300\n", *target);
+     }
+
+     return ( 0 );
+}
+
+void print_usage()
+{
+    printf("\n dtest_ext usage \n\n");
+    printf("s: server\n");
+    printf("h: hostname\n");
+    printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+     int i,c;
+     char hostname[100];
+
+     /* parse arguments */
+     while ((c = getopt(argc, argv, "sh:")) != -1)
+       {
+           switch(c)
+           {
+           case 's':
+                 server = 1;
+                 break;
+           case 'h':
+                 server = 0;
+                 strcpy(hostname, optarg);
+                 break;
+           default:
+                 print_usage();
+                 exit(1);
+               }
+       }
+
+       if (server)
+            printf("Server: using provider OpenIB-ib0\n");
+       else
+            printf("Client: using provider OpenIB-ib0, connect to %s \n", 
+                 hostname);
+
+     /* connect and send rdma buffer information */
+     if (connect_ep(hostname)) 
+           exit(1);
+     
+     if (do_immediate())
+           exit(1);
+
+     if (do_cmp_swap()) 
+           exit(1);
+
+     if (do_fetch_add()) 
+           exit(1);
+
+     return (disconnect_ep());
+}
Index: test/dtest/makefile
===================================================================
--- test/dtest/makefile (revision 5065)
+++ test/dtest/makefile (working copy)
@@ -4,13 +4,18 @@ CFLAGS     = -O2 -g
 DAT_INC = ../../dat/include
 DAT_LIB = /usr/local/lib
 
-all: dtest
+all: dtest dtest_ext
 
 clean:
-     rm -f *.o;touch *.c;rm -f dtest
+     rm -f *.o;touch *.c;rm -f dtest dtest_ext
 
 dtest: ./dtest.c
      $(CC) $(CFLAGS) ./dtest.c -o dtest \
      -DDAPL_PROVIDER='"OpenIB-cma-ip"' \
      -I $(DAT_INC) -L $(DAT_LIB) -ldat
 
+dtest_ext: ./dtest_ext.c
+     $(CC) $(CFLAGS) ./dtest_ext.c -o dtest_ext \
+     -DDAPL_PROVIDER='"OpenIB-cma-ip"' \
+     -I $(DAT_INC) -L $(DAT_LIB) -ldat
+
Index: dapl/include/dapl.h
===================================================================
--- dapl/include/dapl.h (revision 5065)
+++ dapl/include/dapl.h (working copy)
@@ -1,25 +1,28 @@
 /*
- * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
  *
  * This Software is licensed under one of the following licenses:
- *
+ * 
  * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    available from the Open Source Initiative, see
+ *    in the file LICENSE.txt in the root directory. The license is also
+ *    available from the Open Source Initiative, see 
  *    http://www.opensource.org/licenses/cpl.php.
- *
- * 2) under the terms of the "The BSD License" a copy of which is
- *    available from the Open Source Initiative, see
+ * 
+ * 2) under the terms of the "The BSD License" a copy of which is in the file
+ *    LICENSE2.txt in the root directory. The license is also available from
+ *    the Open Source Initiative, see
  *    http://www.opensource.org/licenses/bsd-license.php.
- *
+ * 
  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is available from the Open Source Initiative, see
+ *    copy of which is in the file LICENSE3.txt in the root directory. The
+ *    license is also available from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/gpl-license.php.
- *
+ * 
  * Licensee has the right to choose one of the above licenses.
- *
+ * 
  * Redistributions of source code must retain the above copyright
  * notice and one of the license notices.
- *
+ * 
  * Redistributions in binary form must reproduce both the above copyright
  * notice, one of the license notices in the documentation
  * and/or other materials provided with the distribution.
@@ -61,6 +64,8 @@
 #include "dapl_dummy_util.h"
 #elif OPENIB
 #include "dapl_ib_util.h"
+#elif DET
+#include "dapl_det_util.h"
 #endif
 
 /*********************************************************************
@@ -178,6 +183,11 @@ typedef enum dapl_qp_state
 
 #define DAT_ERROR(Type, SubType) ((DAT_RETURN)(DAT_CLASS_ERROR | Type | SubType))
 
+#ifdef DAT_EXTENSIONS
+#define DAT_ERROR_EXTENSION(Type, ExtType, SubType) \
+     ((DAT_RETURN)(DAT_CLASS_ERROR | Type | ExtType | SubType))
+#endif
+
 /*********************************************************************
  *                                                                   *
  * Typedefs                                                          *
@@ -563,6 +573,15 @@ typedef enum dapl_dto_type
     DAPL_DTO_TYPE_RECV,
     DAPL_DTO_TYPE_RDMA_WRITE,
     DAPL_DTO_TYPE_RDMA_READ,
+#ifdef DAT_IMMEDIATE_DATA
+    DAPL_DTO_TYPE_SEND_IMMED,
+    DAPL_DTO_TYPE_RECV_IMMED,
+    DAPL_DTO_TYPE_RDMA_WRITE_IMMED,
+#endif
+#ifdef DAT_EXTENSIONS
+    DAPL_DTO_TYPE_EXTENSION
+#endif
+
 } DAPL_DTO_TYPE;
 
 typedef enum dapl_cookie_type
@@ -570,6 +589,7 @@ typedef enum dapl_cookie_type
     DAPL_COOKIE_TYPE_NULL,
     DAPL_COOKIE_TYPE_DTO,
     DAPL_COOKIE_TYPE_RMR,
+
 } DAPL_COOKIE_TYPE;
 
 /* DAPL_DTO_COOKIE used as context for DTO WQEs */
@@ -578,6 +598,9 @@ struct dapl_dto_cookie
     DAPL_DTO_TYPE            type;
     DAT_DTO_COOKIE           cookie;
     DAT_COUNT                size; /* used for SEND and RDMA write */
+#ifdef DAT_EXTENSIONS
+    DAT_PVOID                extension;  /* extended DTO ops */
+#endif
 };
 
 /* DAPL_RMR_COOKIE used as context for bind WQEs */
@@ -1116,6 +1139,42 @@ extern DAT_RETURN dapl_srq_set_lw(
      IN      DAT_SRQ_HANDLE,         /* srq_handle           */
      IN      DAT_COUNT);             /* low_watermark        */
 
+#ifdef DAT_IMMEDIATE_DATA
+extern DAT_RETURN dapl_ep_post_send_immed (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN    DAT_UINT32,       /* immediate data */
+     IN    DAT_DTO_FLAGS,          /* dto_flags            */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+
+extern DAT_RETURN dapl_ep_post_recv_immed (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+
+extern DAT_RETURN dapl_ep_post_rdma_write_immed (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN      const DAT_RMR_TRIPLET *,/* remote_iov           */
+     IN    DAT_UINT32,       /* immediate data */
+     IN    DAT_DTO_FLAGS,          /* dto_flags            */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+#endif
+
+#ifdef DAT_EXTENSIONS
+extern DAT_RETURN dapl_extensions(
+     IN      DAT_HANDLE,           /* dat_handle           */
+     IN    DAT_DTO_EXTENSION_OP,   /* extension operation  */
+     IN    va_list );        /* va_list args         */
+
+#endif
+
 /*
  * DAPL internal utility function prototpyes
  */
Index: dapl/include/dapl_debug.h
===================================================================
--- dapl/include/dapl_debug.h (revision 5065)
+++ dapl/include/dapl_debug.h (working copy)
@@ -112,7 +112,16 @@ extern void dapl_internal_dbg_log ( DAPL
 #define DCNT_EVD_DEQUEUE_NOT_FOUND 18
 #define DCNT_TIMER_SET             19
 #define DCNT_TIMER_CANCEL          20
+
+#ifdef DAT_IMMEDIATE_DATA
+#define DCNT_POST_SEND_IMMED       21
+#define DCNT_POST_RECV_IMMED       22
+#define DCNT_POST_RDMA_WRITE_IMMED 23
+#define DCNT_NUM_COUNTERS          24
+#else
 #define DCNT_NUM_COUNTERS          21
+#endif
+
 #define DCNT_ALL_COUNTERS               DCNT_NUM_COUNTERS
 
 #if defined(DAPL_COUNTERS)
Index: dapl/udapl/Makefile
===================================================================
--- dapl/udapl/Makefile (revision 5065)
+++ dapl/udapl/Makefile (working copy)
@@ -80,6 +80,13 @@ ifdef OS_VENDOR
 CFLAGS += -D$(OS_VENDOR)
 endif
 
+# If an implementation supports immdiate data and extensions
+CFLAGS += -DDAT_EXTENSIONS 
+CFLAGS += -DDAT_IMMEDIATE_DATA 
+
+# If an implementation supports DAPL provider specific attributes
+CFLAGS += -DDAPL_PROVIDER_SPECIFIC_ATTR
+
 #
 # dummy provider
 #
@@ -283,6 +290,8 @@ LDFLAGS += -libverbs -lrdmacm
 LDFLAGS += -rpath /usr/local/lib -L /usr/local/lib
 PROVIDER_SRCS  = dapl_ib_util.c dapl_ib_cq.c dapl_ib_qp.c \
                  dapl_ib_cm.c dapl_ib_mem.c
+# implementation supports extensions
+PROVIDER_SRCS += dapl_ib_extensions.c
 endif
 
 UDAPL_SRCS =     dapl_init.c       \
@@ -320,6 +329,9 @@ COMMON_SRCS =   dapl_cookie.c           \
      dapl_ep_post_rdma_write.c     \
      dapl_ep_post_recv.c           \
      dapl_ep_post_send.c           \
+     dapl_ep_post_recv_immed.c     \
+     dapl_ep_post_send_immed.c     \
+     dapl_ep_post_rdma_write_immed.c     \
      dapl_ep_query.c               \
      dapl_ep_util.c                \
      dapl_evd_dequeue.c            \
Index: dapl/common/dapl_ep_post_recv_immed.c
===================================================================
--- dapl/common/dapl_ep_post_recv_immed.c (revision 0)
+++ dapl/common/dapl_ep_post_recv_immed.c (revision 0)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+
+/**********************************************************************
+ *
+ * MODULE: dapl_ep_post_recv.c
+ *
+ * PURPOSE: Endpoint management
+ * Description: Interfaces in this file are completely described in
+ *         the DAPL 1.1 API, Chapter 6, section 5
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl.h"
+#include "dapl_cookie.h"
+#include "dapl_adapter_util.h"
+
+/*
+ * dapl_ep_post_recv_immed
+ *
+ * DAPL Requirements Version xxx, 6.5.11
+ *
+ * Request to receive data over the connection of ep handle into
+ * local_iov. 
+ *
+ * Provide additional message buffer space for 32 bit immediate data.
+ *
+ * Input:
+ *   ep_handle
+ *   num_segments
+ *   local_iov
+ *   user_cookie
+ *   completion_flags
+ *
+ * Output:
+ *   None.
+ *
+ * Returns:
+ *   DAT_SUCCESS
+ *   DAT_INSUFFICIENT_RESOURCES
+ *   DAT_INVALID_PARAMETER
+ *   DAT_INVALID_STATE
+ *   DAT_PROTECTION_VIOLATION
+ *   DAT_PROVILEGES_VIOLATION
+ */
+DAT_RETURN
+dapl_ep_post_recv_immed (
+     IN    DAT_EP_HANDLE           ep_handle,
+     IN    DAT_COUNT         num_segments,
+     IN    DAT_LMR_TRIPLET         *local_iov,
+     IN    DAT_DTO_COOKIE          user_cookie,
+     IN    DAT_COMPLETION_FLAGS    completion_flags )
+{
+    DAPL_EP            *ep_ptr;
+    DAPL_COOKIE        *cookie;
+    DAT_RETURN         dat_status;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_API,
+             "dapl_ep_post_recv_immed(%p, %d, %p, %P, %x)\n",
+             ep_handle,
+             num_segments,
+             local_iov,
+             user_cookie.as_64,
+             completion_flags);
+    DAPL_CNTR (DCNT_POST_RECV);
+
+    if ( DAPL_BAD_HANDLE (ep_handle, DAPL_MAGIC_EP) )
+    {
+     dat_status = DAT_ERROR (DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+     goto bail;
+    }
+
+    ep_ptr = (DAPL_EP *) ep_handle;
+
+    /*
+     * Synchronization ok since this buffer is only used for receive
+     * requests, which aren't allowed to race with each other.
+     */
+    dat_status = dapls_dto_cookie_alloc (&ep_ptr->recv_buffer,
+                             DAPL_DTO_TYPE_RECV_IMMED,
+                             user_cookie,
+                             &cookie);
+    if ( DAT_SUCCESS != dat_status)
+    {
+     goto bail;
+    }
+
+    /*
+     * Take reference before posting to avoid race conditions with
+     * completions
+     */
+    dapl_os_atomic_inc (&ep_ptr->recv_count);
+
+    /*
+     * Invoke provider specific routine to post DTO
+     */
+    dat_status = dapls_ib_post_recv_immed (ep_ptr, cookie, num_segments, local_iov);
+
+    if ( dat_status != DAT_SUCCESS )
+    {
+     dapl_os_atomic_dec (&ep_ptr->recv_count);
+     dapls_cookie_dealloc (&ep_ptr->recv_buffer, cookie);
+    }
+
+bail:
+    dapl_dbg_log (DAPL_DBG_TYPE_RTN,
+             "dapl_ep_post_recv_immed () returns 0x%x\n",
+             dat_status);
+
+    return dat_status;
+}
Index: dapl/common/dapl_ep_post_rdma_write.c
===================================================================
--- dapl/common/dapl_ep_post_rdma_write.c (revision 5065)
+++ dapl/common/dapl_ep_post_rdma_write.c (working copy)
@@ -78,7 +78,7 @@ dapl_ep_post_rdma_write (
     DAT_RETURN         dat_status;
 
     dapl_dbg_log (DAPL_DBG_TYPE_API,
-             "dapl_ep_post_rdma_write (%p, %d, %p, %p, %p, %x)\n",
+             "dapl_ep_post_rdma_write (%p, %d, %p, %P, %p, %x)\n",
              ep_handle, 
              num_segments, 
              local_iov, 
@@ -92,6 +92,9 @@ dapl_ep_post_rdma_write (
                                  local_iov, 
                                  user_cookie, 
                                  remote_iov, 
+#if DAT_IMMEDIATE_DATA
+                       0, 0,
+#endif
                                  completion_flags, 
                                  DAPL_DTO_TYPE_RDMA_WRITE,
                                  OP_RDMA_WRITE);
Index: dapl/common/dapl_ep_post_rdma_write_immed.c
===================================================================
--- dapl/common/dapl_ep_post_rdma_write_immed.c (revision 0)
+++ dapl/common/dapl_ep_post_rdma_write_immed.c (revision 0)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+
+/**********************************************************************
+ * 
+ * MODULE: dapl_ep_post_rdma_write_immed.c
+ *
+ * PURPOSE: Endpoint management
+ * Description: Interfaces in this file are completely described in
+ *         the DAPL 1.1 API, Chapter 6, section 5
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl_ep_util.h"
+
+/*
+ * dapl_ep_post_rdma_write_immed
+ *
+ * DAPL Requirements Version xxx, 6.5.13
+ *
+ * Request the xfer of all data specified by the local_iov over the
+ * connection of ep handle Endpint into the remote_iov
+ *
+ * Input:
+ *   ep_handle
+ *   num_segments
+ *   local_iov
+ *   user_cookie
+ *   remote_iov
+ *   immed_data
+ *   dto_flags
+ *   compltion_flags
+ *
+ * Output:
+ *   None.
+ *
+ * Returns:
+ *   DAT_SUCCESS
+ *   DAT_INSUFFICIENT_RESOURCES
+ *   DAT_INVALID_PARAMETER
+ *   DAT_INVALID_STATE
+ *   DAT_LENGTH_ERROR
+ *   DAT_PROTECTION_VIOLATION
+ *   DAT_PRIVILEGES_VIOLATION
+ */
+DAT_RETURN
+dapl_ep_post_rdma_write_immed (
+     IN    DAT_EP_HANDLE           ep_handle,
+     IN    DAT_COUNT         num_segments,
+     IN    DAT_LMR_TRIPLET         *local_iov,
+     IN    DAT_DTO_COOKIE          user_cookie,
+     IN    const DAT_RMR_TRIPLET   *remote_iov,
+     IN    DAT_UINT32        immed_data,
+     IN    DAT_DTO_FLAGS           dto_flags,
+     IN    DAT_COMPLETION_FLAGS    completion_flags )
+{
+    DAT_RETURN         dat_status;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_API,
+             "dapl_ep_post_rdma_write_immed (%p, %d, %p, %llx, %p, %x, %x, %x)\n",
+             ep_handle, 
+             num_segments, 
+             local_iov, 
+             user_cookie.as_64,
+             remote_iov, 
+             immed_data,
+             dto_flags,
+             completion_flags);
+    DAPL_CNTR(DCNT_POST_RDMA_WRITE_IMMED);
+
+    dat_status = dapl_ep_post_send_req(ep_handle, 
+                                 num_segments, 
+                                 local_iov, 
+                                 user_cookie, 
+                                 remote_iov, 
+                       immed_data,
+                       dto_flags,
+                                 completion_flags, 
+                                 DAPL_DTO_TYPE_RDMA_WRITE_IMMED,
+                                 OP_RDMA_WRITE_IMMED);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_RTN,
+           "dapl_ep_post_rdma_write_immed () returns 0x%x",
+           dat_status);
+
+
+    return dat_status;
+}
Index: dapl/common/dapl_ia_query.c
===================================================================
--- dapl/common/dapl_ia_query.c     (revision 5065)
+++ dapl/common/dapl_ia_query.c     (working copy)
@@ -167,6 +167,14 @@ dapl_ia_query (
 #if !defined(__KDAPL__)
      provider_attr->pz_support                 = DAT_PZ_UNIQUE;
 #endif /* !KDAPL */
+
+     /*
+     *  Have provider set their own.
+     */
+#ifdef DAPL_PROVIDER_SPECIFIC_ATTR
+     dapls_set_provider_specific_attr(provider_attr);
+#endif
+
      /*
       * Set up evd_stream_merging_supported options. Note there is
       * one bit per allowable combination, using the ordinal
Index: dapl/common/dapl_adapter_util.h
===================================================================
--- dapl/common/dapl_adapter_util.h (revision 5065)
+++ dapl/common/dapl_adapter_util.h (working copy)
@@ -256,6 +256,21 @@ dapls_ib_wait_object_wait (
      IN u_int32_t                  timeout);
 #endif
 
+#ifdef DAPL_PROVIDER_SPECIFIC_ATTR
+void 
+dapls_set_provider_specific_attr(
+     IN DAT_PROVIDER_ATTR          *provider_attr );
+#endif
+
+#ifdef DAT_EXTENSIONS
+void
+dapls_cqe_to_event_extension(
+     IN DAPL_EP              *ep_ptr,
+     IN DAPL_COOKIE                *cookie,
+     IN ib_work_completion_t       *cqe_ptr,
+     OUT DAT_EVENT                 *event_ptr);
+#endif
+
 /*
  * Values for provider DAT_NAMED_ATTR
  */
@@ -272,6 +287,8 @@ dapls_ib_wait_object_wait (
 #include "dapl_dummy_dto.h"
 #elif OPENIB
 #include "dapl_ib_dto.h"
+#elif DET
+#include "dapl_det_dto.h"
 #endif
 
 
Index: dapl/common/dapl_ep_post_send.c
===================================================================
--- dapl/common/dapl_ep_post_send.c (revision 5065)
+++ dapl/common/dapl_ep_post_send.c (working copy)
@@ -75,7 +75,7 @@ dapl_ep_post_send (
     DAT_RETURN         dat_status;
 
     dapl_dbg_log (DAPL_DBG_TYPE_API,
-             "dapl_ep_post_send (%p, %d, %p, %p, %x)\n",
+             "dapl_ep_post_send (%p, %d, %p, %P, %x)\n",
              ep_handle, 
              num_segments, 
              local_iov, 
@@ -88,6 +88,9 @@ dapl_ep_post_send (
                                  local_iov,
                                  user_cookie,
                                  &remote_iov,
+#if DAT_IMMEDIATE_DATA
+                       0, 0,
+#endif
                                  completion_flags,
                                  DAPL_DTO_TYPE_SEND,
                                  OP_SEND);
Index: dapl/common/dapl_provider.c
===================================================================
--- dapl/common/dapl_provider.c     (revision 5065)
+++ dapl/common/dapl_provider.c     (working copy)
@@ -221,7 +221,19 @@ DAT_PROVIDER g_dapl_provider_template =
     &dapl_srq_post_recv,
     &dapl_srq_query,
     &dapl_srq_resize,
-    &dapl_srq_set_lw
+    &dapl_srq_set_lw,
+    
+#ifdef DAT_IMMEDIATE_DATA
+    /* dat-2.0 */
+    &dapl_ep_post_send_immed,
+    &dapl_ep_post_recv_immed,
+    &dapl_ep_post_rdma_write_immed,
+#endif
+
+#ifdef DAT_EXTENSIONS
+    /* dat-2.0 */
+    &dapl_extensions
+#endif
 
 };
 #endif /* __KDAPL__ */
Index: dapl/common/dapl_ep_post_send_immed.c
===================================================================
--- dapl/common/dapl_ep_post_send_immed.c (revision 0)
+++ dapl/common/dapl_ep_post_send_immed.c (revision 0)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+
+/**********************************************************************
+ * 
+ * MODULE: dapl_ep_post_send_immed.c
+ *
+ * PURPOSE: Endpoint management
+ * Description: Interfaces in this file are completely described in
+ *         the DAPL 1.1 API, Chapter 6, section 5
+ *
+ * $Id:$
+ **********************************************************************/
+
+#include "dapl_ep_util.h"
+
+/*
+ * dapl_ep_post_send_immed
+ *
+ * DAPL Requirements Version xxx, 6.5.10
+ *
+ * Request a transfer of all the data from the local_iov over
+ * the connection of the ep handle Endpoint to the remote side.
+ *
+ * Input:
+ *   ep_handle
+ *   num_segments
+ *   local_iov
+ *   user_cookie
+ *   immed_data
+ *   dto_flags
+ *   completion_flags
+ *
+ * Output:
+ *   None
+ * Returns:
+ *   DAT_SUCCESS
+ *   DAT_INSUFFICIENT_RESOURCES
+ *   DAT_INVALID_PARAMETER
+ *   DAT_INVALID_STATE
+ *   DAT_PROTECTION_VIOLATION
+ *   DAT_PRIVILEGES_VIOLATION
+ */
+DAT_RETURN
+dapl_ep_post_send_immed (
+     IN    DAT_EP_HANDLE           ep_handle,
+     IN    DAT_COUNT         num_segments,
+     IN    DAT_LMR_TRIPLET         *local_iov,
+     IN    DAT_DTO_COOKIE          user_cookie,
+     IN    DAT_UINT32        immed_data,
+     IN    DAT_DTO_FLAGS           dto_flags,
+     IN    DAT_COMPLETION_FLAGS    completion_flags )
+{
+    DAT_RMR_TRIPLET    remote_iov = {0,0,0,0};
+    DAT_RETURN         dat_status;
+
+    dapl_dbg_log (DAPL_DBG_TYPE_API,
+             "dapl_ep_post_send_immed (%p, %d, %p, %llx, %x, %x, %x)\n",
+             ep_handle, 
+             num_segments, 
+             local_iov, 
+             user_cookie.as_64,
+             immed_data,
+             dto_flags,
+             completion_flags);
+    DAPL_CNTR(DCNT_POST_SEND_IMMED);
+
+    dat_status = dapl_ep_post_send_req(ep_handle,
+                                 num_segments,
+                                 local_iov,
+                                 user_cookie,
+                                 &remote_iov,
+                       immed_data,
+                       dto_flags,
+                                 completion_flags,
+                                 DAPL_DTO_TYPE_SEND_IMMED,
+                                 OP_SEND_IMMED);
+
+    dapl_dbg_log (DAPL_DBG_TYPE_RTN,
+             "dapl_ep_post_send () returns 0x%x\n",
+               dat_status);
+
+
+    return dat_status;
+}
Index: dapl/common/dapl_ep_util.c
===================================================================
--- dapl/common/dapl_ep_util.c      (revision 5065)
+++ dapl/common/dapl_ep_util.c      (working copy)
@@ -367,9 +367,13 @@ dapl_ep_post_send_req (
     IN     DAT_LMR_TRIPLET         *local_iov,
     IN     DAT_DTO_COOKIE          user_cookie,
     IN     const DAT_RMR_TRIPLET   *remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+    IN  DAT_UINT32           immed_data,
+    IN  DAT_DTO_FLAGS        dto_flags,
+#endif
     IN     DAT_COMPLETION_FLAGS    completion_flags,
     IN  DAPL_DTO_TYPE        dto_type,
-    IN  int                  op_type)
+    IN  int                  op_type )
 {
     DAPL_EP            *ep_ptr;
     DAPL_COOKIE        *cookie;
@@ -412,6 +416,10 @@ dapl_ep_post_send_req (
                              num_segments,
                              local_iov,
                              remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+                             immed_data,
+                             dto_flags,
+#endif
                              completion_flags );
 
     if ( dat_status != DAT_SUCCESS )
Index: dapl/common/dapl_ep_util.h
===================================================================
--- dapl/common/dapl_ep_util.h      (revision 5065)
+++ dapl/common/dapl_ep_util.h      (working copy)
@@ -67,6 +67,10 @@ dapl_ep_post_send_req (
     IN     DAT_LMR_TRIPLET         *local_iov,
     IN     DAT_DTO_COOKIE          user_cookie,
     IN     const DAT_RMR_TRIPLET   *remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+    IN  DAT_UINT32           immed_data,
+    IN  DAT_DTO_FLAGS        dto_flags,
+#endif
     IN     DAT_COMPLETION_FLAGS    completion_flags,
     IN  DAPL_DTO_TYPE        dto_type,
     IN  int                  op_type );
Index: dapl/common/dapl_ep_post_rdma_read.c
===================================================================
--- dapl/common/dapl_ep_post_rdma_read.c  (revision 5065)
+++ dapl/common/dapl_ep_post_rdma_read.c  (working copy)
@@ -93,6 +93,9 @@ dapl_ep_post_rdma_read (
                                  local_iov, 
                                  user_cookie, 
                                  remote_iov, 
+#if DAT_IMMEDIATE_DATA
+                       0, 0,
+#endif
                                  completion_flags, 
                                  DAPL_DTO_TYPE_RDMA_READ,
                                  OP_RDMA_READ);
Index: dapl/common/dapl_evd_util.c
===================================================================
--- dapl/common/dapl_evd_util.c     (revision 5065)
+++ dapl/common/dapl_evd_util.c     (working copy)
@@ -502,6 +502,21 @@ dapli_evd_eh_print_cqe (
 #ifdef DAPL_DBG
     static char *optable[] =
     {
+#ifdef OPENIB
+     /* different order for openib verbs */
+    "OP_RDMA_WRITE",
+     "OP_RDMA_WRITE_IMMED",
+     "OP_SEND",
+     "OP_SEND_IMMED",
+     "OP_RDMA_READ",
+     "OP_COMP_AND_SWAP",
+     "OP_FETCH_AND_ADD",
+     "OP_RECEIVE",
+     "OP_RECEIVE_IMMED",
+     "OP_RECEIVE_RDMA_IMMED",
+     "OP_BIND_MW",
+     "OP_INVALID",
+#else
      "OP_SEND",
      "OP_RDMA_READ",
      "OP_RDMA_WRITE",
@@ -509,6 +524,7 @@ dapli_evd_eh_print_cqe (
      "OP_FETCH_AND_ADD",
      "OP_RECEIVE",
      "OP_BIND_MW",
+#endif
      0
     };
 
@@ -1030,7 +1046,20 @@ dapli_evd_cqe_to_event (
      {
          DAPL_COOKIE_BUFFER  *buffer;
 
+#ifdef DAT_EXTENSIONS
+         if ( DAPL_DTO_TYPE_EXTENSION == cookie->val.dto.type )
+         {
+           dapls_cqe_to_event_extension(ep_ptr, cookie, cqe_ptr, event_ptr);
+           break;
+         }
+#endif
+         
+#if DAT_IMMEDIATE_DATA
+         if ( DAPL_DTO_TYPE_RECV == cookie->val.dto.type ||
+           DAPL_DTO_TYPE_RECV_IMMED == cookie->val.dto.type )
+#else      
          if ( DAPL_DTO_TYPE_RECV == cookie->val.dto.type )
+#endif
          {
            dapl_os_atomic_dec (&ep_ptr->recv_count);
            buffer = &ep_ptr->recv_buffer;
@@ -1048,6 +1077,16 @@ dapli_evd_cqe_to_event (
            cookie->val.dto.cookie;
          event_ptr->event_data.dto_completion_event_data.status = dto_status;
 
+#ifdef DAT_IMMEDIATE_DATA
+         event_ptr->event_data.dto_completion_event_data.operation = 
+                             DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr);
+
+         if ( DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr) == DAT_RECEIVE_IMMED ||
+           DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr) == DAT_RECEIVE_RDMA_IMMED)
+                 event_ptr->event_data.dto_completion_event_data.immed_data =
+                             DAPL_GET_CQE_IMMED_DATA(cqe_ptr);
+#endif
+
 #ifdef DAPL_DBG
          if (dto_status == DAT_DTO_SUCCESS)
          {
@@ -1055,18 +1094,42 @@ dapli_evd_cqe_to_event (
 
            ibtype = DAPL_GET_CQE_OPTYPE (cqe_ptr);
 
-           dapl_os_assert ((ibtype == OP_SEND &&
+           dapl_dbg_log(DAPL_DBG_TYPE_WARN, 
+                 " dapli_evd_cqe_to_event: OP type ib=%d, cookie=%d)\n", 
+                 ibtype, cookie->val.dto.type);
+#ifdef DAT_EXTENSIONS
+           if (cookie->val.dto.type != DAPL_DTO_TYPE_EXTENSION)
+#endif
+                 dapl_os_assert ((ibtype == OP_SEND &&
                         cookie->val.dto.type == DAPL_DTO_TYPE_SEND)
-                       || (ibtype == OP_RECEIVE &&
-                           cookie->val.dto.type == DAPL_DTO_TYPE_RECV)
-                       || (ibtype == OP_RDMA_WRITE &&
-                           cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE)
-                       || (ibtype == OP_RDMA_READ &&
-                           cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_READ));
+#ifdef DAT_IMMEDIATE_DATA
+                        || (ibtype == OP_RECEIVE &&
+                            (cookie->val.dto.type == DAPL_DTO_TYPE_RECV ||
+                             cookie->val.dto.type == DAPL_DTO_TYPE_RECV_IMMED))
+                       || (ibtype == OP_RECEIVE_IMMED &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_RECV_IMMED)
+                       || (ibtype == OP_RECEIVE_RDMA_IMMED &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_RECV_IMMED)
+                        || (ibtype == OP_SEND_IMMED &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_SEND_IMMED)
+                       || (ibtype == OP_RDMA_WRITE_IMMED &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE_IMMED)
+#else
+                       || (ibtype == OP_RECEIVE &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_RECV)
+#endif
+                       || (ibtype == OP_RDMA_WRITE &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE)
+                       || (ibtype == OP_RDMA_READ &&
+                            cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_READ));
            }
 #endif /* DAPL_DBG */
 
          if ( cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||
+#ifdef DAT_IMMEDIATE_DATA
+           cookie->val.dto.type == DAPL_DTO_TYPE_SEND_IMMED ||
+           cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE_IMMED ||
+#endif
             cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE )
          {
            /* Get size from DTO; CQE value may be off.  */
@@ -1113,6 +1176,7 @@ dapli_evd_cqe_to_event (
          dapls_cookie_dealloc (&ep_ptr->req_buffer, cookie);
          break;
      }
+
      default:
      {
          dapl_os_assert (!"Invalid Operation type");
Index: dapl/common/dapl_debug.c
===================================================================
--- dapl/common/dapl_debug.c  (revision 5065)
+++ dapl/common/dapl_debug.c  (working copy)
@@ -86,6 +86,11 @@ char  *dapl_dbg_counter_names[] = {
      "dapl_evd_not_found",
      "dapls_timer_set",
      "dapls_timer_cancel",
+#ifdef DAT_IMMEDIATE_DATA
+     "dapls_ep_post_send_immed",
+     "dapls_ep_post_recv_immed",
+     "dapls_ep_post_rdma_write_immed",
+#endif
 };
 
 void dapl_dump_cntr( int cntr )
Index: dapl/openib_cma/dapl_ib_dto.h
===================================================================
--- dapl/openib_cma/dapl_ib_dto.h   (revision 5065)
+++ dapl/openib_cma/dapl_ib_dto.h   (working copy)
@@ -35,7 +35,7 @@
  *
  *   Description: 
  *
- *   The uDAPL openib provider - DTO operations and CQE macros 
+ *   The OpenIB uCMA provider - DTO operations and CQE macros 
  *
  ****************************************************************************
  *            Source Control System Information
@@ -119,7 +119,6 @@ dapls_ib_post_recv (
      return DAT_SUCCESS;
 }
 
-
 /*
  * dapls_ib_post_send
  *
@@ -133,6 +132,10 @@ dapls_ib_post_send (
      IN  DAT_COUNT                 segments,
      IN  DAT_LMR_TRIPLET           *local_iov,
      IN  const DAT_RMR_TRIPLET     *remote_iov,
+#ifdef DAT_IMMEDIATE_DATA
+     IN  DAT_UINT32                immed_data,
+     IN  DAT_DTO_FLAGS       dto_flags,
+#endif
      IN  DAT_COMPLETION_FLAGS      completion_flags)
 {
      dapl_dbg_log(DAPL_DBG_TYPE_EP,
@@ -191,8 +194,12 @@ dapls_ib_post_send (
 
      if (cookie != NULL) 
            cookie->val.dto.size = total_len;
-     
-     if ((op_type == OP_RDMA_WRITE) || (op_type == OP_RDMA_READ)) {
+
+     if ((op_type == OP_RDMA_WRITE) || 
+#ifdef DAT_IMMEDIATE_DATA
+         (op_type == OP_RDMA_WRITE_IMMED) ||
+#endif
+         (op_type == OP_RDMA_READ)) {
            wr.wr.rdma.remote_addr = remote_iov->target_address;
            wr.wr.rdma.rkey = remote_iov->rmr_context;
            dapl_dbg_log(DAPL_DBG_TYPE_EP, 
@@ -200,6 +207,14 @@ dapls_ib_post_send (
                       wr.wr.rdma.rkey, wr.wr.rdma.remote_addr);
      }
 
+#ifdef DAT_IMMEDIATE_DATA
+         if ((op_type == OP_SEND_IMMED) || (op_type == OP_RDMA_WRITE_IMMED)) {
+           dapl_dbg_log(DAPL_DBG_TYPE_EP, 
+                      " post_snd: IMMED=0x%x\n", immed_data);
+           wr.imm_data = immed_data;
+         }
+#endif
+
      /* inline data for send or write ops */
      if ((total_len <= ibt_ptr->max_inline_send) && 
         ((op_type == OP_SEND) || (op_type == OP_RDMA_WRITE))) 
@@ -224,6 +239,182 @@ dapls_ib_post_send (
      return DAT_SUCCESS;
 }
 
+#ifdef DAT_IMMEDIATE_DATA
+
+STATIC _INLINE_ DAT_RETURN 
+dapls_ib_post_recv_immed (
+     IN  DAPL_EP       *ep_ptr,
+     IN  DAPL_COOKIE         *cookie,
+     IN  DAT_COUNT           segments,
+     IN  DAT_LMR_TRIPLET     *local_iov )
+{
+     /* Nothing more to do, IB already provides space in descriptor */
+     return (dapls_ib_post_recv( ep_ptr, cookie, segments, local_iov));
+}
+
+/* map Work Completions to DAPL WR operations */
+STATIC _INLINE_ DAT_DTOS dapls_cqe_dtos_opcode(ib_work_completion_t *cqe_p)
+{
+     switch (cqe_p->opcode) {
+     case IBV_WC_SEND:
+           if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+                 return (DAT_SEND_IMMED);
+           else
+                 return (DAT_SEND);
+     case IBV_WC_RDMA_WRITE:
+           if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+                 return (DAT_RDMA_WRITE_IMMED);
+           else
+                 return (DAT_RDMA_WRITE);
+     case IBV_WC_RDMA_READ:
+           return (DAT_RDMA_READ);
+     case IBV_WC_BIND_MW:
+           return (DAT_BIND_MW);
+     case IBV_WC_RECV:
+           if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+                 return (DAT_RECEIVE_IMMED);
+           else
+                 return (DAT_RECEIVE);
+#ifdef DAT_EXTENSIONS
+     case IBV_WC_COMP_SWAP:
+           return (DAT_EXTENSION);
+     case IBV_WC_FETCH_ADD:
+           return (DAT_EXTENSION);
+#endif
+     case IBV_WC_RECV_RDMA_WITH_IMM:
+           return (DAT_RECEIVE_RDMA_IMMED);
+     default:
+           return (DAT_INVALID);
+     }
+}
+#define DAPL_GET_CQE_DTOS_OPTYPE(cqe_p) dapls_cqe_dtos_opcode(cqe_p)
+
+#endif
+
+#ifdef DAT_EXTENSIONS
+/*
+ * dapls_ib_post_ext_send
+ *
+ * Provider specific extended Post SEND function for atomics
+ *   OP_COMP_AND_SWAP and OP_FETCH_AND_ADD
+ */
+STATIC _INLINE_ DAT_RETURN 
+dapls_ib_post_ext_send (
+     IN  DAPL_EP             *ep_ptr,
+     IN  ib_send_op_type_t         op_type,
+     IN  DAPL_COOKIE               *cookie,
+     IN  DAT_COUNT                 segments,
+     IN  DAT_LMR_TRIPLET           *local_iov,
+     IN  const DAT_RMR_TRIPLET     *remote_iov,
+     IN  DAT_UINT64                compare_add,
+     IN  DAT_UINT64                swap,
+     IN  DAT_COMPLETION_FLAGS      completion_flags)
+{
+     dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                " post_snd: ep %p op %d ck %p sgs",
+                "%d l_iov %p r_iov %p f %d\n",
+                ep_ptr, op_type, cookie, segments, local_iov, 
+                remote_iov, completion_flags);
+
+     ib_data_segment_t ds_array[DEFAULT_DS_ENTRIES];
+     ib_data_segment_t *ds_array_p;
+     struct ibv_send_wr wr;
+     struct ibv_send_wr *bad_wr;
+     DAT_COUNT i, total_len;
+     
+     dapl_dbg_log(DAPL_DBG_TYPE_EP,
+                " post_snd: ep %p cookie %p segs %d l_iov %p\n",
+                ep_ptr, cookie, segments, local_iov);
+
+     if(segments <= DEFAULT_DS_ENTRIES) 
+           ds_array_p = ds_array;
+     else
+           ds_array_p = 
+                 dapl_os_alloc(segments * sizeof(ib_data_segment_t));
+
+     if (NULL == ds_array_p)
+           return (DAT_INSUFFICIENT_RESOURCES);
+     
+     /* setup the work request */
+     wr.next = 0;
+     wr.opcode = op_type;
+     wr.num_sge = 0;
+     wr.send_flags = 0;
+     wr.wr_id = (uint64_t)(uintptr_t)cookie;
+     wr.sg_list = ds_array_p;
+     total_len = 0;
+
+     for (i = 0; i < segments; i++ ) {
+           if ( !local_iov[i].segment_length )
+                 continue;
+
+           ds_array_p->addr = (uint64_t) local_iov[i].virtual_address;
+           ds_array_p->length = local_iov[i].segment_length;
+           ds_array_p->lkey = local_iov[i].lmr_context;
+           
+           dapl_dbg_log(DAPL_DBG_TYPE_EP, 
+                      " post_snd: lkey 0x%x va %p len %d\n",
+                      ds_array_p->lkey, ds_array_p->addr, 
+                      ds_array_p->length );
+
+           total_len += ds_array_p->length;
+           wr.num_sge++;
+           ds_array_p++;
+     }
+
+     if (cookie != NULL) 
+           cookie->val.dto.size = total_len;
+
+     switch (op_type) {
+     case OP_COMP_AND_SWAP:
+           /* OP_COMP_AND_SWAP has direct IBAL wr_type mapping */
+           dapl_dbg_log(DAPL_DBG_TYPE_EP, 
+                      " post_snd: OP_COMP_AND_SWAP=%lx,"
+                      "%lx rkey 0x%x va %#016Lx\n",
+                      compare_add, swap, remote_iov->rmr_context,
+                      remote_iov->target_address);
+           
+           wr.wr.atomic.compare_add = compare_add;
+           wr.wr.atomic.swap = swap;
+           wr.wr.atomic.remote_addr = remote_iov->target_address;
+           wr.wr.atomic.rkey = remote_iov->rmr_context;
+           break;
+     case OP_FETCH_AND_ADD:
+           /* OP_FETCH_AND_ADD has direct IBAL wr_type mapping */
+           dapl_dbg_log(DAPL_DBG_TYPE_EP, 
+                      " post_snd: OP_FETCH_AND_ADD=%lx,"
+                      "%lx rkey 0x%x va %#016Lx\n",
+                      compare_add, remote_iov->rmr_context,
+                      remote_iov->target_address);
+
+           wr.wr.atomic.compare_add = compare_add;
+           wr.wr.atomic.remote_addr = remote_iov->target_address;
+           wr.wr.atomic.rkey = remote_iov->rmr_context;
+           break;
+     default:
+           break;
+     }
+
+     /* set completion flags in work request */
+     wr.send_flags |= (DAT_COMPLETION_SUPPRESS_FLAG & 
+                       completion_flags) ? 0 : IBV_SEND_SIGNALED;
+     wr.send_flags |= (DAT_COMPLETION_BARRIER_FENCE_FLAG & 
+                       completion_flags) ? IBV_SEND_FENCE : 0;
+     wr.send_flags |= (DAT_COMPLETION_SOLICITED_WAIT_FLAG & 
+                       completion_flags) ? IBV_SEND_SOLICITED : 0;
+
+     dapl_dbg_log(DAPL_DBG_TYPE_EP, 
+                " post_snd: op 0x%x flags 0x%x sglist %p, %d\n", 
+                wr.opcode, wr.send_flags, wr.sg_list, wr.num_sge);
+
+     if (ibv_post_send(ep_ptr->qp_handle->cm_id->qp, &wr, &bad_wr))
+           return( dapl_convert_errno(EFAULT,"ibv_recv") );
+     
+     dapl_dbg_log(DAPL_DBG_TYPE_EP," post_snd: returned\n");
+     return DAT_SUCCESS;
+}
+#endif
+
 STATIC _INLINE_ DAT_RETURN 
 dapls_ib_optional_prv_dat(
      IN  DAPL_CR       *cr_ptr,
@@ -233,13 +424,17 @@ dapls_ib_optional_prv_dat(
     return DAT_SUCCESS;
 }
 
+/* map Work Completions to DAPL WR operations */
 STATIC _INLINE_ int dapls_cqe_opcode(ib_work_completion_t *cqe_p)
 {
      switch (cqe_p->opcode) {
      case IBV_WC_SEND:
            return (OP_SEND);
      case IBV_WC_RDMA_WRITE:
-           return (OP_RDMA_WRITE);
+           if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+                 return (OP_RDMA_WRITE_IMMED);
+           else
+                 return (OP_RDMA_WRITE);
      case IBV_WC_RDMA_READ:
            return (OP_RDMA_READ);
      case IBV_WC_COMP_SWAP:
@@ -249,14 +444,18 @@ STATIC _INLINE_ int dapls_cqe_opcode(ib_
      case IBV_WC_BIND_MW:
            return (OP_BIND_MW);
      case IBV_WC_RECV:
-           return (OP_RECEIVE);
+           if (cqe_p->wc_flags & IBV_WC_WITH_IMM)
+                 return (OP_RECEIVE_IMMED);
+           else
+                 return (OP_RECEIVE);
      case IBV_WC_RECV_RDMA_WITH_IMM:
-           return (OP_RECEIVE_IMM);
+           return (OP_RECEIVE_RDMA_IMMED);
      default:
            return (OP_INVALID);
      }
 }
 
+
 #define DAPL_GET_CQE_OPTYPE(cqe_p) dapls_cqe_opcode(cqe_p)
 #define DAPL_GET_CQE_WRID(cqe_p) ((ib_work_completion_t*)cqe_p)->wr_id
 #define DAPL_GET_CQE_STATUS(cqe_p) ((ib_work_completion_t*)cqe_p)->status
Index: dapl/openib_cma/dapl_ib_util.c
===================================================================
--- dapl/openib_cma/dapl_ib_util.c  (revision 5065)
+++ dapl/openib_cma/dapl_ib_util.c  (working copy)
@@ -35,7 +35,7 @@
  *
  *   Description: 
  *
- *   The uDAPL openib provider - init, open, close, utilities, work thread
+ *   The OpenIB uCMA provider - init, open, close, utilities, work thread
  *
  ****************************************************************************
  *            Source Control System Information
@@ -64,7 +64,6 @@ static const char rcsid[] = "$Id:  $";
 #include <net/if.h>     /* for struct ifreq */
 #include <net/if_arp.h> /* for ARPHRD_INFINIBAND */
 
-
 int g_dapl_loopback_connection = 0;
 int g_ib_pipe[2];
 ib_thread_state_t g_ib_thread_state = 0;
@@ -342,6 +341,7 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HC
            struct timespec   sleep, remain;
            sleep.tv_sec = 0;
            sleep.tv_nsec = 10000000; /* 10 ms */
+           write(g_ib_pipe[1], "w", sizeof "w");
            dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 
                       " ib_thread_destroy: wait on hca %p destroy\n");
            nanosleep (&sleep, &remain);
@@ -727,7 +727,7 @@ void dapli_thread(void *arg) 
      int               ret,idx,fds;
      char              rbuf[2];
      
-     dapl_dbg_log (DAPL_DBG_TYPE_CM,
+     dapl_dbg_log (DAPL_DBG_TYPE_UTIL,
                  " ib_thread(%d,0x%x): ENTER: pipe %d ucma %d\n",
                  getpid(), g_ib_thread, g_ib_pipe[0], rdma_get_fd());
 
@@ -767,7 +767,7 @@ void dapli_thread(void *arg) 
                  ufds[idx].revents = 0;
                  uhca[idx] = hca;
 
-                 dapl_dbg_log(DAPL_DBG_TYPE_CM,
+                 dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
                        " ib_thread(%d) poll_fd: hca[%d]=%p, async=%d"
                        " pipe=%d cm=%d cq=d\n",
                        getpid(), hca, ufds[idx-1].fd, 
@@ -783,14 +783,14 @@ void dapli_thread(void *arg) 
            dapl_os_unlock(&g_hca_lock);
                 ret = poll(ufds, fds, -1); 
            if (ret <= 0) {
-                 dapl_dbg_log(DAPL_DBG_TYPE_WARN,
+                 dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
                             " ib_thread(%d): ERR %s poll\n",
                             getpid(),strerror(errno));
                 dapl_os_lock(&g_hca_lock);
                  continue;
            }
 
-           dapl_dbg_log(DAPL_DBG_TYPE_CM,
+           dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
                  " ib_thread(%d) poll_event: "
                  " async=0x%x pipe=0x%x cm=0x%x cq=0x%x\n",
                  getpid(), ufds[idx-1].revents, ufds[0].revents, 
@@ -834,3 +834,54 @@ void dapli_thread(void *arg) 
      dapl_os_unlock(&g_hca_lock);  
 }
 
+#ifdef DAPL_PROVIDER_SPECIFIC_ATTR
+/*
+ * dapls_set_provider_specific_attr
+ *
+ * Input:
+ *   attr_ptr    Pointer provider attributes
+ *
+ * Output:
+ *   none
+ *
+ * Returns:
+ *   void
+ */
+DAT_NAMED_ATTR   ib_attrs[] = {
+ 
+#ifdef DAT_EXTENSIONS
+    {
+    DAT_EXTENSION_ATTR,
+    DAT_EXTENSION_ATTR_TRUE
+    },
+    {
+    DAT_EXTENSION_ATTR_VERSION,
+    DAT_EXTENSION_ATTR_VERSION_VALUE
+    },
+    {
+    DAT_EXTENSION_ATTR_FETCH_AND_ADD,
+    DAT_EXTENSION_ATTR_TRUE
+    },
+    {
+    DAT_EXTENSION_ATTR_CMP_AND_SWAP,
+    DAT_EXTENSION_ATTR_TRUE
+    },
+#else
+     {
+    "DAT_EXTENSION_INTERFACE",
+    "FALSE"
+    },
+#endif
+};
+
+#define SPEC_ATTR_SIZE(x) ( sizeof(x)/sizeof(DAT_NAMED_ATTR) )
+
+void dapls_set_provider_specific_attr(
+     IN DAT_PROVIDER_ATTR    *attr_ptr )
+{
+    attr_ptr->num_provider_specific_attr = SPEC_ATTR_SIZE(ib_attrs);
+    attr_ptr->provider_specific_attr = ib_attrs;
+}
+
+#endif
+
Index: dapl/openib_cma/dapl_ib_mem.c
===================================================================
--- dapl/openib_cma/dapl_ib_mem.c   (revision 5065)
+++ dapl/openib_cma/dapl_ib_mem.c   (working copy)
@@ -25,9 +25,9 @@
 
 /**********************************************************************
  * 
- * MODULE: dapl_det_mem.c
+ * MODULE: dapl_ib_mem.c
  *
- * PURPOSE: Intel DET APIs: Memory windows, registration,
+ * PURPOSE: OpenIB uCMA provider Memory windows, registration,
  *           and protection domain 
  *
  * $Id: $
@@ -65,6 +65,10 @@ dapls_convert_privileges(IN DAT_MEM_PRIV
 {
      int   access = 0;
 
+     dapl_dbg_log(DAPL_DBG_TYPE_WARN, 
+                " dapls_convert_privileges: 0x%x\n", 
+                privileges );
+
      /*
       * if (DAT_MEM_PRIV_LOCAL_READ_FLAG & privileges) do nothing
       */
@@ -72,12 +76,13 @@ dapls_convert_privileges(IN DAT_MEM_PRIV
            access |= IBV_ACCESS_LOCAL_WRITE;
      if (DAT_MEM_PRIV_REMOTE_WRITE_FLAG & privileges)
            access |= IBV_ACCESS_REMOTE_WRITE;
-     if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
-           access |= IBV_ACCESS_REMOTE_READ;
-     if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
-           access |= IBV_ACCESS_REMOTE_READ;
-     if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges)
+     if (DAT_MEM_PRIV_REMOTE_READ_FLAG & privileges) 
            access |= IBV_ACCESS_REMOTE_READ;
+     
+#ifdef DAT_EXTENSIONS
+     if (DAT_MEM_PRIV_EXT_REMOTE_ATOMIC & privileges) 
+           access |= IBV_ACCESS_REMOTE_ATOMIC;
+#endif
 
      return access;
 }
Index: dapl/openib_cma/dapl_ib_extensions.c
===================================================================
--- dapl/openib_cma/dapl_ib_extensions.c  (revision 0)
+++ dapl/openib_cma/dapl_ib_extensions.c  (revision 0)
@@ -0,0 +1,374 @@
+/*
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+/**********************************************************************
+ * 
+ * MODULE: dapl_ib_extensions.c
+ *
+ * PURPOSE:  Extensions routines for OpenIB uCMA provider
+ *
+ * $Id: $
+ **********************************************************************/
+
+#include "dapl.h"
+#include "dapl_adapter_util.h"
+#include "dapl_evd_util.h"
+#include "dapl_ib_util.h"
+#include "dapl_ep_util.h"
+#include "dapl_cookie.h"
+#include <stdarg.h>
+
+DAT_RETURN
+dapli_post_cmp_and_swap(
+     IN       DAT_EP_HANDLE        ep_handle,
+     IN       DAT_UINT64           cmp_val,    
+     IN       DAT_UINT64           swap_val,
+     IN       DAT_LMR_TRIPLET      *local_iov,
+     IN       DAT_DTO_COOKIE       user_cookie,
+     IN const DAT_RMR_TRIPLET      *remote_iov,
+     IN       DAT_COMPLETION_FLAGS flags );
+
+DAT_RETURN
+dapli_post_fetch_and_add(
+     IN       DAT_EP_HANDLE        ep_handle,
+     IN       DAT_UINT64           add_val, 
+     IN       DAT_LMR_TRIPLET      *local_iov,
+     IN       DAT_DTO_COOKIE       user_cookie,
+     IN const DAT_RMR_TRIPLET      *remote_iov,
+     IN       DAT_COMPLETION_FLAGS flags );
+
+
+/*
+ * dapl_extensions
+ *
+ * Process extension requests
+ *
+ * Input:
+ *   ext_type,
+ *   ...
+ *
+ * Output:
+ *   Depends....
+ *
+ * Returns:
+ *   DAT_SUCCESS
+ *   DAT_NOT_IMPLEMENTED
+ *      .....
+ *
+ */
+
+DAT_RETURN
+dapl_extensions(IN DAT_HANDLE dat_handle, 
+           IN DAT_DTO_EXTENSION_OP ext_op, 
+           IN va_list args)
+{
+     DAT_EP_HANDLE               ep;
+     DAT_LMR_TRIPLET             *lmr_p;
+     DAT_DTO_COOKIE              cookie;
+     const DAT_RMR_TRIPLET       *rmr_p;
+     DAT_UINT64            dat_uint64a, dat_uint64b;
+     DAT_COMPLETION_FLAGS        comp_flags;
+
+     DAT_RETURN status = DAT_NOT_IMPLEMENTED;
+
+     dapl_dbg_log(DAPL_DBG_TYPE_API,
+                "dapl_extensions(hdl %p operation %d, ...)\n",
+                dat_handle, ext_op);
+
+     switch ((int)ext_op)
+     {
+     
+     case DAT_DTO_EXTENSION_CMP_AND_SWAP:
+           dapl_dbg_log(DAPL_DBG_TYPE_RTN, 
+                      " CMP_AND_SWAP extension call\n");
+
+           ep          = dat_handle;           /* ep_handle */
+           dat_uint64a = va_arg( args, DAT_UINT64); /* cmp_value */
+           dat_uint64b = va_arg( args, DAT_UINT64); /* swap_value */
+           lmr_p       = va_arg( args, DAT_LMR_TRIPLET*); 
+           cookie      = va_arg( args, DAT_DTO_COOKIE);  
+           rmr_p       = va_arg( args, const DAT_RMR_TRIPLET*);
+           comp_flags  = va_arg( args, DAT_COMPLETION_FLAGS);
+
+           status = dapli_post_cmp_and_swap(ep,
+                                   dat_uint64a,
+                                   dat_uint64b,
+                                   lmr_p,
+                                   cookie,
+                                   rmr_p,
+                                   comp_flags );
+           break;
+
+     case DAT_DTO_EXTENSION_FETCH_AND_ADD:
+           dapl_dbg_log(DAPL_DBG_TYPE_RTN, 
+                      " FETCH_AND_ADD extension call\n");
+           
+           ep          = dat_handle;           /* ep_handle */
+           dat_uint64a = va_arg( args, DAT_UINT64); /* add value */
+           lmr_p       = va_arg( args, DAT_LMR_TRIPLET*);  
+           cookie      = va_arg( args, DAT_DTO_COOKIE);
+           rmr_p       = va_arg( args, const DAT_RMR_TRIPLET*); 
+           comp_flags  = va_arg( args, DAT_COMPLETION_FLAGS);   
+           
+           status = dapli_post_fetch_and_add(ep,
+                                    dat_uint64a,
+                                     lmr_p,
+                                     cookie,
+                                     rmr_p,
+                                    comp_flags );
+           break;
+
+     default:
+           dapl_dbg_log(DAPL_DBG_TYPE_ERR, 
+                      "unsupported extension(%d)\n", (int)ext_op);
+     }
+     
+     return(status);
+}
+
+
+DAT_RETURN
+dapli_post_cmp_and_swap(IN       DAT_EP_HANDLE       ep_handle,
+                 IN       DAT_UINT64           cmp_val,    
+                 IN       DAT_UINT64           swap_val,
+                 IN       DAT_LMR_TRIPLET      *local_iov,
+                 IN       DAT_DTO_COOKIE       user_cookie,
+                 IN const DAT_RMR_TRIPLET      *remote_iov,
+                 IN       DAT_COMPLETION_FLAGS flags )
+{
+     DAPL_EP     *ep_ptr;
+     ib_qp_handle_t    qp_ptr;
+     DAPL_COOKIE *cookie;
+     DAT_RETURN  dat_status = DAT_SUCCESS;
+
+     dapl_dbg_log(DAPL_DBG_TYPE_API,
+                " post_cmp_and_swap: ep %p cmp_val %d "
+                "swap_val %d cookie 0x%x, r_iov %p, flags 0x%x\n",
+                ep_handle, (unsigned)cmp_val, (unsigned)swap_val, 
+                (unsigned)user_cookie.as_64, remote_iov, flags);
+
+     if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP))
+           return(DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));
+
+     if ((NULL == remote_iov) || (NULL == local_iov))
+           return DAT_INVALID_PARAMETER;
+
+     ep_ptr = (DAPL_EP *) ep_handle;
+     qp_ptr = ep_ptr->qp_handle;
+
+     /*
+     * Synchronization ok since this buffer is only used for send
+     * requests, which aren't allowed to race with each other.
+     * only if completion is expected
+     */
+     if (!(DAT_COMPLETION_SUPPRESS_FLAG & flags)) {
+
+           dat_status = dapls_dto_cookie_alloc(
+                                   &ep_ptr->req_buffer,
+                                   DAPL_DTO_TYPE_EXTENSION,
+                                   user_cookie,
+                                   &cookie );
+
+           if ( dat_status != DAT_SUCCESS )
+                 goto bail;
+           
+           /*
+           * Take reference before posting to avoid race conditions with
+           * completions
+           */
+           dapl_os_atomic_inc(&ep_ptr->req_count);
+     }
+
+     /*
+     * Invoke provider specific routine to post DTO
+     */
+     dat_status = dapls_ib_post_ext_send(ep_ptr,     
+                                 OP_COMP_AND_SWAP,
+                                 cookie, 
+                                 1, 
+                                 local_iov, 
+                                 remote_iov,
+                                 cmp_val,      /* compare or add */
+                                 swap_val,     /* swap */
+                                 flags);
+
+     if (dat_status != DAT_SUCCESS) {
+           if ( cookie != NULL ) {
+                 dapl_os_atomic_dec(&ep_ptr->req_count);
+                 dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
+           }
+     }
+
+bail:
+     return dat_status;
+
+}
+
+DAT_RETURN
+dapli_post_fetch_and_add(IN       DAT_EP_HANDLE            ep_handle,
+                 IN       DAT_UINT64          add_val,    
+                 IN       DAT_LMR_TRIPLET     *local_iov,
+                 IN       DAT_DTO_COOKIE      user_cookie,
+                 IN const DAT_RMR_TRIPLET     *remote_iov,
+                 IN       DAT_COMPLETION_FLAGS      flags )
+{
+     DAPL_EP           *ep_ptr;
+     DAPL_COOKIE *cookie;
+     DAT_RETURN  dat_status = DAT_SUCCESS;
+
+     dapl_dbg_log (DAPL_DBG_TYPE_API,
+           " post_fetch_and_add: ep %p add_val %d local_iov"
+           "%p cookie 0x%x, r_iov %p, flags 0x%x\n",
+           ep_handle, (unsigned)add_val, local_iov,
+           (unsigned)user_cookie.as_64, remote_iov, flags);
+
+     if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP))
+           return(DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));
+     
+     if ((NULL == remote_iov) || (NULL == local_iov)) 
+           return DAT_INVALID_PARAMETER;
+     
+     ep_ptr = (DAPL_EP *) ep_handle;
+
+     /*
+     * Synchronization ok since this buffer is only used for send
+     * requests, which aren't allowed to race with each other.
+     * only if completion is expected
+     */
+     if (!(DAT_COMPLETION_SUPPRESS_FLAG & flags)) {
+
+           dat_status = dapls_dto_cookie_alloc(
+                                   &ep_ptr->req_buffer,
+                                   DAPL_DTO_TYPE_EXTENSION,
+                                   user_cookie,
+                                   &cookie);
+
+           if (dat_status != DAT_SUCCESS) 
+                 goto bail;
+           
+           /*
+           * Take reference before posting to avoid race conditions with
+           * completions
+           */
+           dapl_os_atomic_inc(&ep_ptr->req_count);
+     }
+
+     /*
+     * Invoke provider specific routine to post DTO
+     */
+     dat_status = dapls_ib_post_ext_send(ep_ptr,     
+                                 OP_FETCH_AND_ADD,
+                                 cookie, 
+                                 1, 
+                                 local_iov, 
+                                 remote_iov,
+                                 add_val,      /* compare or add */
+                                 0,            /* swap */
+                                 flags);
+
+     if (dat_status != DAT_SUCCESS) {
+           if (cookie != NULL ) {
+                 dapl_os_atomic_dec (&ep_ptr->req_count);
+                 dapls_cookie_dealloc (&ep_ptr->req_buffer, cookie);
+           }
+     }
+
+bail:
+     return dat_status;
+}
+
+/* 
+ * New provider routine to process extended DTO events 
+ */
+void
+dapls_cqe_to_event_extension(IN DAPL_EP              *ep_ptr,
+                      IN DAPL_COOKIE           *cookie,
+                      IN ib_work_completion_t  *cqe_ptr,
+                      IN DAT_EVENT       *event_ptr)
+{
+     uint32_t ibtype;
+     DAPL_COOKIE_BUFFER *buffer;
+     DAT_DTO_COMPLETION_EVENT_DATA *dto_event = 
+                 &event_ptr->event_data.dto_completion_event_data;
+                       
+     dapl_dbg_log(DAPL_DBG_TYPE_EVD,
+                " cqe_to_event_ext: event_ptr %p dto_event %p\n",
+                event_ptr, dto_event);
+               
+
+     if ( DAPL_DTO_TYPE_RECV == cookie->val.dto.type ||
+          DAPL_DTO_TYPE_RECV_IMMED == cookie->val.dto.type ) {
+           dapl_os_atomic_dec (&ep_ptr->recv_count);
+           buffer = &ep_ptr->recv_buffer;
+     }
+     else {
+           dapl_os_atomic_dec (&ep_ptr->req_count);
+           buffer = &ep_ptr->req_buffer;
+     }
+
+     /* update DTO event data and then the extension */
+     event_ptr->event_number = DAT_DTO_COMPLETION_EVENT;
+     dto_event->operation = DAT_EXTENSION;
+     dto_event->ep_handle = cookie->ep;
+     dto_event->user_cookie = cookie->val.dto.cookie;
+     dto_event->status = dapls_ib_get_dto_status(cqe_ptr);
+
+     if (dto_event->status != DAT_DTO_SUCCESS )
+           return;
+     
+     /* get operation type from CQ work completion entry */
+     ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);
+        
+     switch (ibtype)   {
+     case OP_COMP_AND_SWAP:
+                dapl_dbg_log (DAPL_DBG_TYPE_EVD,
+                                " cqe_to_event_ext: COMP_AND_SWAP_RESP\n");
+                /* original data is returned in LMR provided with post */
+           dto_event->extension.type = DAT_DTO_EXTENSION_CMP_AND_SWAP;
+           break;
+
+     case OP_FETCH_AND_ADD:
+                dapl_dbg_log (DAPL_DBG_TYPE_EVD,
+                                " cqe_to_event_ext: FETCH_AND_ADD_RESP\n");
+           /* original data is returned in LMR provided with post */
+           dto_event->extension.type = DAT_DTO_EXTENSION_FETCH_AND_ADD;
+           break;
+
+     default:
+           dapl_dbg_log(DAPL_DBG_TYPE_DTO_COMP_ERR,
+                 "Extension completion ERROR: unknown op = 0x%x\n",
+                      ibtype);
+     }
+     
+     if (cookie->val.dto.type == DAPL_DTO_TYPE_SEND ||
+         cookie->val.dto.type == DAPL_DTO_TYPE_SEND_IMMED ||
+         cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE_IMMED ||
+         cookie->val.dto.type == DAPL_DTO_TYPE_RDMA_WRITE )      
+           /* Get size from DTO; CQE value may be off.  */
+           dto_event->transfered_length = cookie->val.dto.size;
+     else 
+           dto_event->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);
+     
+     dapls_cookie_dealloc(buffer, cookie);
+}
Index: dapl/openib_cma/dapl_ib_qp.c
===================================================================
--- dapl/openib_cma/dapl_ib_qp.c    (revision 5065)
+++ dapl/openib_cma/dapl_ib_qp.c    (working copy)
@@ -25,9 +25,9 @@
 
 /**********************************************************************
  *
- * MODULE: dapl_det_qp.c
+ * MODULE: dapl_ib_qp.c
  *
- * PURPOSE: QP routines for access to DET Verbs
+ * PURPOSE: OpenIB uCMA QP routines 
  *
  * $Id: $
  **********************************************************************/
Index: dapl/openib_cma/dapl_ib_util.h
===================================================================
--- dapl/openib_cma/dapl_ib_util.h  (revision 5065)
+++ dapl/openib_cma/dapl_ib_util.h  (working copy)
@@ -35,7 +35,7 @@
  *
  *   Description: 
  *
- *   The uDAPL openib provider - definitions, prototypes,
+ *   The OpenIB uCMA provider - definitions, prototypes,
  *
  ****************************************************************************
  *            Source Control System Information
@@ -123,15 +123,16 @@ typedef struct ibv_comp_channel *ib_wait
 
 /* DTO OPs, ordered for DAPL ENUM definitions */
 #define OP_RDMA_WRITE           IBV_WR_RDMA_WRITE
-#define OP_RDMA_WRITE_IMM       IBV_WR_RDMA_WRITE_WITH_IMM
+#define OP_RDMA_WRITE_IMMED     IBV_WR_RDMA_WRITE_WITH_IMM
 #define OP_SEND                 IBV_WR_SEND
-#define OP_SEND_IMM             IBV_WR_SEND_WITH_IMM
+#define OP_SEND_IMMED           IBV_WR_SEND_WITH_IMM
 #define OP_RDMA_READ            IBV_WR_RDMA_READ
 #define OP_COMP_AND_SWAP        IBV_WR_ATOMIC_CMP_AND_SWP
 #define OP_FETCH_AND_ADD        IBV_WR_ATOMIC_FETCH_AND_ADD
-#define OP_RECEIVE              7   /* internal op */
-#define OP_RECEIVE_IMM       8   /* internel op */
-#define OP_BIND_MW              9   /* internal op */
+#define OP_RECEIVE              0x7   /* internal op */
+#define OP_RECEIVE_IMMED     0x8   /* internel op */
+#define OP_RECEIVE_RDMA_IMMED      0x9   /* internal op */
+#define OP_BIND_MW              0xa   /* internal op */
 #define OP_INVALID           0xff
 
 /* Definitions to map QP state */
@@ -295,7 +296,8 @@ dapl_convert_errno( IN int err, IN const
     if (!err)    return DAT_SUCCESS;
     
 #if DAPL_DBG
-    if ((err != EAGAIN) && (err != ETIME) && (err != ETIMEDOUT))
+    if ((err != EAGAIN) && (err != ETIME) && 
+     (err != ETIMEDOUT) && (err != EINTR))
      dapl_dbg_log (DAPL_DBG_TYPE_ERR," %s %s\n", str, strerror(err));
 #endif 
 
Index: dapl/openib_cma/dapl_ib_cq.c
===================================================================
--- dapl/openib_cma/dapl_ib_cq.c    (revision 5065)
+++ dapl/openib_cma/dapl_ib_cq.c    (working copy)
@@ -35,7 +35,7 @@
  *
  *   Description: 
  *
- *   The uDAPL openib provider - completion queue
+ *   The OpenIB uCMA provider - completion queue
  *
  ****************************************************************************
  *            Source Control System Information
@@ -498,7 +498,10 @@ dapls_ib_wait_object_wait(IN ib_wait_obj
      if (timeout != DAT_TIMEOUT_INFINITE)
            timeout_ms = timeout/1000;
 
-     status = poll(&cq_fd, 1, timeout_ms);
+     /* restart syscall */
+     while ((status = poll(&cq_fd, 1, timeout_ms)) == -1 )
+           if (errno == EINTR)
+                 continue;
 
      /* returned event */
      if (status > 0) {
@@ -511,6 +514,8 @@ dapls_ib_wait_object_wait(IN ib_wait_obj
      /* timeout */
      } else if (status == 0) 
            status = ETIMEDOUT;
+     else 
+           status = errno;
      
      dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 
                 " cq_object_wait: RET evd %p ibv_cq %p ibv_ctx %p %s\n",
Index: dat/include/dat/udat.h
===================================================================
--- dat/include/dat/udat.h    (revision 5065)
+++ dat/include/dat/udat.h    (working copy)
@@ -1,31 +1,51 @@
 /*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 2002-2004, Network Appliance, Inc. All rights reserved.
  *
- * This Software is licensed under one of the following licenses:
- * 
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see 
+ * This Software is licensed under both of the following two licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0". The license is also
+ *    available from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/cpl.php.
- * 
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
+ *
+ * OR
+ *
+ * 2) under the terms of the "The BSD License". The license is also available
+ *    from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/bsd-license.php.
- * 
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is in the file LICENSE3.txt in the root directory. The
- *    license is also available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- * 
- * Licensee has the right to choose one of the above licenses.
- * 
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- * 
+ *
+ * Licensee has the right to choose either one of the above two licenses.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain both the above copyright
+ * notice and either one of the license notices.
+ *
  * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
+ * notice, either one of the license notices in the documentation
  * and/or other materials provided with the distribution.
+ *
+ * Neither the name of Network Appliance, Inc. nor the names of other DAT
+ * Collaborative contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 /****************************************************************
Index: dat/include/dat/dat_redirection.h
===================================================================
--- dat/include/dat/dat_redirection.h     (revision 5065)
+++ dat/include/dat/dat_redirection.h     (working copy)
@@ -59,10 +59,10 @@ typedef struct dat_provider DAT_PROVIDER
  * This would allow a good compiler to avoid indirection overhead when
  * making function calls.
  */
-
 #define DAT_HANDLE_TO_PROVIDER(handle) (*(DAT_PROVIDER **)(handle))
 #endif
 
+
 #define DAT_IA_QUERY(ia, evd, ia_msk, ia_ptr, p_msk, p_ptr) \
      (*DAT_HANDLE_TO_PROVIDER (ia)->ia_query_func) (\
                 (ia),               \
@@ -395,6 +395,45 @@ typedef struct dat_provider DAT_PROVIDER
            (lbuf),              \
            (cookie))
 
+#ifdef DAT_IMMEDIATE_DATA
+#define DAT_EP_POST_SEND_IMMED(ep, size, lbuf, cookie, immed, dflags, flags) \
+     (*DAT_HANDLE_TO_PROVIDER (ep)->ep_post_send_immed_func) (\
+           (ep),                \
+           (size),              \
+           (lbuf),              \
+           (cookie),            \
+           (immed),             \
+           (dflags),            \
+           (flags))
+
+#define DAT_EP_POST_RECV_IMMED(ep, size, lbuf, cookie, flags) \
+     (*DAT_HANDLE_TO_PROVIDER (ep)->ep_post_recv_immed_func) (\
+           (ep),                \
+           (size),              \
+           (lbuf),              \
+           (cookie),            \
+           (flags))
+
+#define DAT_EP_POST_RDMA_WRITE_IMMED(ep, size, lbuf, cookie, rbuf, immed, dflags, flags) \
+     (*DAT_HANDLE_TO_PROVIDER (ep)->ep_post_rdma_write_immed_func) (\
+           (ep),                \
+           (size),              \
+           (lbuf),              \
+           (cookie),            \
+           (rbuf),              \
+           (immed),             \
+           (dflags),            \
+           (flags))
+#endif
+
+#ifdef DAT_EXTENSIONS
+#define DAT_EXTENSION(handle, op, args) \
+     (*DAT_HANDLE_TO_PROVIDER (handle)->extension_func) (\
+           (handle), \
+           (op), \
+           (args))
+#endif
+
 /***************************************************************
  *
  * FUNCTION PROTOTYPES
@@ -720,4 +759,41 @@ typedef DAT_RETURN (*DAT_SRQ_POST_RECV_F
      IN      DAT_LMR_TRIPLET *,    /* local_iov            */
      IN      DAT_DTO_COOKIE );     /* user_cookie          */
 
+#ifdef DAT_IMMEDIATE_DATA
+typedef DAT_RETURN (*DAT_EP_POST_SEND_IMMED_FUNC) (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN    DAT_UINT32,       /* immediate data */
+     IN    DAT_DTO_FLAGS,          /* dto_flags            */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+
+typedef DAT_RETURN (*DAT_EP_POST_RECV_IMMED_FUNC) (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+
+typedef DAT_RETURN (*DAT_EP_POST_RDMA_WRITE_IMMED_FUNC) (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN      const DAT_RMR_TRIPLET *,/* remote_iov           */
+     IN    DAT_UINT32,       /* immediate data */
+     IN    DAT_DTO_FLAGS,          /* dto_flags            */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+#endif
+
+#ifdef DAT_EXTENSIONS
+#include <stdarg.h>
+typedef DAT_RETURN (*DAT_EXTENSION_FUNC) (
+     IN    DAT_HANDLE,       /* dat handle           */
+     IN    DAT_DTO_EXTENSION_OP,   /* extension operation  */
+        IN va_list );        /* va_list        */
+#endif
+
+
 #endif /* _DAT_REDIRECTION_H_ */
Index: dat/include/dat/dat.h
===================================================================
--- dat/include/dat/dat.h     (revision 5065)
+++ dat/include/dat/dat.h     (working copy)
@@ -119,6 +119,27 @@ typedef DAT_HANDLE       DAT_RMR_HANDLE;
 typedef DAT_HANDLE       DAT_RSP_HANDLE;
 typedef DAT_HANDLE       DAT_SRQ_HANDLE;
 
+/* PROTOTYPE: immediate data and extensions */
+#ifdef DAT_IMMEDIATE_DATA
+typedef enum dat_dtos
+{
+     DAT_SEND,
+     DAT_SEND_IMMED,
+     DAT_RDMA_WRITE,
+     DAT_RDMA_WRITE_IMMED,
+     DAT_RDMA_READ,
+     DAT_RECEIVE,
+     DAT_RECEIVE_WITH_INVALIDATE,
+     DAT_RECEIVE_IMMED,
+     DAT_RECEIVE_RDMA_IMMED,
+     DAT_BIND_MW,
+#ifdef DAT_EXTENSIONS
+     DAT_EXTENSION,
+#endif
+     DAT_INVALID
+} DAT_DTOS;
+#endif
+
 /* dat NULL handles */
 #define DAT_HANDLE_NULL ((DAT_HANDLE)NULL)
 
@@ -176,6 +197,15 @@ typedef enum dat_psp_flags
     DAT_PSP_PROVIDER_FLAG            = 0x01  /* Provider creates an Endpoint */
 } DAT_PSP_FLAGS;
 
+#ifdef DAT_IMMEDIATE_DATA
+typedef enum dat_dto_flags
+{
+    DAT_DTO_IMMED_FLAG               = 0x1,
+    DAT_DTO_IMMED_CONFIRM_FLAG       = 0x2
+
+} DAT_DTO_FLAGS;
+#endif
+
 /*
  * Memory Buffers
  *
@@ -259,7 +289,6 @@ typedef struct dat_rmr_triplet
  */
 
 /* Memory privileges */
-
 typedef enum dat_mem_priv_flags
 {
     DAT_MEM_PRIV_NONE_FLAG           = 0x00,
@@ -267,7 +296,11 @@ typedef enum dat_mem_priv_flags
     DAT_MEM_PRIV_REMOTE_READ_FLAG    = 0x02,
     DAT_MEM_PRIV_LOCAL_WRITE_FLAG    = 0x10,
     DAT_MEM_PRIV_REMOTE_WRITE_FLAG   = 0x20,
-    DAT_MEM_PRIV_ALL_FLAG            = 0x33
+    DAT_MEM_PRIV_MW_BIND_FLAG        = 0x40,
+    DAT_MEM_PRIV_ALL_FLAG            = 0x73,
+#ifdef DAT_EXTENSIONS
+    DAT_MEM_PRIV_EXTENSION           = 0x10000
+#endif
 } DAT_MEM_PRIV_FLAGS;
 
 /* For backward compatibility with DAT-1.0, memory privileges values are
@@ -712,6 +745,10 @@ typedef enum dat_dto_completion_status
 
 /* Completion group structs (six total) */
 
+#ifdef DAT_EXTENSIONS
+#include <dat/dat_extensions.h>
+#endif
+
 /* DTO completion event data */
 /* transfered_length is not defined if status is not DAT_SUCCESS */
 typedef struct dat_dto_completion_event_data
@@ -719,7 +756,15 @@ typedef struct dat_dto_completion_event_
     DAT_EP_HANDLE               ep_handle;
     DAT_DTO_COOKIE              user_cookie;
     DAT_DTO_COMPLETION_STATUS   status;
-    DAT_VLEN                    transfered_length;
+    DAT_VLEN                 transfered_length;
+#ifdef DAT_IMMEDIATE_DATA
+    DAT_DTOS                 operation;
+    DAT_RMR_CONTEXT          rmr_context;
+    DAT_UINT32               immed_data;
+#endif
+#ifdef DAT_EXTENSIONS
+    DAT_DTO_EXTENSION_EVENT_DATA   extension;
+#endif
 } DAT_DTO_COMPLETION_EVENT_DATA;
 
     /* RMR bind  completion event data */
@@ -854,11 +899,11 @@ typedef enum dat_event_number
     DAT_ASYNC_ERROR_EP_BROKEN                    = 0x08003,
     DAT_ASYNC_ERROR_TIMED_OUT                    = 0x08004,
     DAT_ASYNC_ERROR_PROVIDER_INTERNAL_ERROR      = 0x08005,
-    DAT_SOFTWARE_EVENT                           = 0x10001
+    DAT_SOFTWARE_EVENT                           = 0x10001,
+
 } DAT_EVENT_NUMBER;
 
 /* Union for event Data */
-
 typedef union dat_event_data
 {
     DAT_DTO_COMPLETION_EVENT_DATA      dto_completion_event_data;
@@ -1222,6 +1267,41 @@ extern DAT_RETURN dat_srq_set_lw (
      IN      DAT_SRQ_HANDLE,         /* srq_handle           */
      IN      DAT_COUNT);             /* low_watermark        */
 
+#ifdef DAT_IMMEDIATE_DATA
+extern DAT_RETURN dat_ep_post_send_immed (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN    DAT_UINT32,       /* immediate data */
+     IN    DAT_DTO_FLAGS,          /* dto_flags            */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+
+extern DAT_RETURN dat_ep_post_recv_immed (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+
+extern DAT_RETURN dat_ep_post_rdma_write_immed (
+     IN      DAT_EP_HANDLE,        /* ep_handle            */
+     IN      DAT_COUNT,            /* num_segments         */
+     IN      DAT_LMR_TRIPLET *,    /* local_iov            */
+     IN      DAT_DTO_COOKIE,       /* user_cookie          */
+     IN      const DAT_RMR_TRIPLET *,/* remote_iov           */
+     IN    DAT_UINT32,       /* immediate data */
+     IN    DAT_DTO_FLAGS,          /* dto_flags            */
+     IN      DAT_COMPLETION_FLAGS ); /* completion_flags     */
+#endif
+
+#ifdef DAT_EXTENSIONS
+extern DAT_RETURN dat_extension(
+     IN    DAT_HANDLE,
+     IN      DAT_DTO_EXTENSION_OP,
+     IN    ... );
+#endif
+
 /*
  * DAT registry functions.
  *
Index: dat/include/dat/dat_error.h
===================================================================
--- dat/include/dat/dat_error.h     (revision 5065)
+++ dat/include/dat/dat_error.h     (working copy)
@@ -1,31 +1,51 @@
 /*
- * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 2002-2004, Network Appliance, Inc. All rights reserved.
  *
- * This Software is licensed under one of the following licenses:
- * 
- * 1) under the terms of the "Common Public License 1.0" a copy of which is
- *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see 
+ * This Software is licensed under both of the following two licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0". The license is also
+ *    available from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/cpl.php.
- * 
- * 2) under the terms of the "The BSD License" a copy of which is in the file
- *    LICENSE2.txt in the root directory. The license is also available from
- *    the Open Source Initiative, see
+ *
+ * OR
+ *
+ * 2) under the terms of the "The BSD License". The license is also available
+ *    from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/bsd-license.php.
- * 
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
- *    copy of which is in the file LICENSE3.txt in the root directory. The
- *    license is also available from the Open Source Initiative, see
- *    http://www.opensource.org/licenses/gpl-license.php.
- * 
- * Licensee has the right to choose one of the above licenses.
- * 
- * Redistributions of source code must retain the above copyright
- * notice and one of the license notices.
- * 
+ *
+ * Licensee has the right to choose either one of the above two licenses.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain both the above copyright
+ * notice and either one of the license notices.
+ *
  * Redistributions in binary form must reproduce both the above copyright
- * notice, one of the license notices in the documentation
+ * notice, either one of the license notices in the documentation
  * and/or other materials provided with the distribution.
+ *
+ * Neither the name of Network Appliance, Inc. nor the names of other DAT
+ * Collaborative contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 /***********************************************************
@@ -47,17 +67,15 @@
 
 /*
  *
- * All return codes are actually a 3-way tuple:
- *
- * type: DAT_RETURN_CLASS DAT_RETURN_TYPE DAT_RETURN_SUBTYPE
- * bits: 31-30            29-16           15-0
+ * All return codes are actually a 4-way tuple:
  *
- *    3                   2                   1
- *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | C | DAT_RETURN_TYPE           | DAT_RETURN_SUBTYPE            |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * type: CLASS    RETURN_TYPE   EXTENSION_SUBTYPE     SUBTYPE
+ * bits: 31-30    29-16         15-8                  7-0
  *
+ * +-------------------------------------------------------------------------+
+ * |3130 | 2928272625242322212019181716 | 15141312111009080 | 706054003020100|
+ * |CLAS | DAT_TYPE_STATUS              | EXTENSION_SUBTYPE | SUBTYPE        |
+ * +-------------------------------------------------------------------------+
  */
 
 /*
@@ -70,8 +88,13 @@
  * DAT Error bits
  */
 #define DAT_TYPE_MASK             0x3fff0000 /* mask for DAT_TYPE_STATUS bits */
-#define DAT_SUBTYPE_MASK          0x0000FFFF /* mask for DAT_SUBTYPE_STATUS bits */
+#define DAT_SUBTYPE_MASK          0x000000FF /* mask for DAT_SUBTYPE_STATUS bits */
 
+#ifdef DAT_EXTENSIONS
+/* Mask and macro for new extension subtype bits */
+#define DAT_EXTENSION_SUBTYPE_MASK    0x0000FF00 /* mask for DAT_EXTENSION_SUBTYPE_STATUS bits */
+#define DAT_GET_EXTENSION_SUBTYPE(status) ((DAT_UINT32)(status) & DAT_EXTENSION_SUBTYPE_MASK)
+#endif
 /*
  * Determining the success of an operation is best done with a macro;
  * each of these returns a boolean value.
Index: dat/include/dat/udat_redirection.h
===================================================================
--- dat/include/dat/udat_redirection.h    (revision 5065)
+++ dat/include/dat/udat_redirection.h    (working copy)
@@ -199,13 +199,12 @@ typedef DAT_RETURN (*DAT_EVD_SET_UNWAITA
 typedef DAT_RETURN (*DAT_EVD_CLEAR_UNWAITABLE_FUNC) (
      IN DAT_EVD_HANDLE);           /* evd_handle           */
 
-
 #include <dat/dat_redirection.h>
 
 struct dat_provider
 {
     const char *                        device_name;
-    DAT_PVOID                           extension;
+    DAT_PVOID                      extension;
 
     DAT_IA_OPEN_FUNC                    ia_open_func;
     DAT_IA_QUERY_FUNC                   ia_query_func;
@@ -294,6 +293,19 @@ struct dat_provider
     DAT_SRQ_QUERY_FUNC                  srq_query_func;
     DAT_SRQ_RESIZE_FUNC                 srq_resize_func;
     DAT_SRQ_SET_LW_FUNC                 srq_set_lw_func;
+
+#ifdef DAT_IMMEDIATE_DATA
+    /* udat-2.0 immediate data */
+    DAT_EP_POST_SEND_IMMED_FUNC         ep_post_send_immed_func;
+    DAT_EP_POST_RECV_IMMED_FUNC         ep_post_recv_immed_func;
+    DAT_EP_POST_RDMA_WRITE_IMMED_FUNC   ep_post_rdma_write_immed_func;
+#endif
+    
+#ifdef DAT_EXTENSIONS
+    /* udat-2.0 extensions */
+    DAT_EXTENSION_FUNC                  extension_func;
+#endif
+
 };
 
 #endif /* _UDAT_REDIRECTION_H_ */
Index: dat/include/dat/dat_extensions.h
===================================================================
--- dat/include/dat/dat_extensions.h      (revision 0)
+++ dat/include/dat/dat_extensions.h      (revision 0)
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ * 
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    in the file LICENSE.txt in the root directory. The license is also
+ *    available from the Open Source Initiative, see 
+ *    http://www.opensource.org/licenses/cpl.php.
+ * 
+ * 2) under the terms of the "The BSD License" a copy of which is in the file
+ *    LICENSE2.txt in the root directory. The license is also available from
+ *    the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ * 
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is in the file LICENSE3.txt in the root directory. The
+ *    license is also available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ * 
+ * Licensee has the right to choose one of the above licenses.
+ * 
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ * 
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+/**********************************************************************
+ *
+ * HEADER: dat_extensions.h
+ *
+ * PURPOSE: defines the extensions to the DAT API for uDAPL.
+ *
+ * Description: Header file for "uDAPL: User Direct Access Programming
+ *         Library, Version: 1.2"
+ *
+ * Mapping rules:
+ *      All global symbols are prepended with "DAT_" or "dat_"
+ *      All DAT objects have an 'api' tag which, such as 'ep' or 'lmr'
+ *      The method table is in the provider definition structure.
+ *
+ *
+ **********************************************************************/
+#ifndef _DAT_EXTENSIONS_H_
+
+extern int dat_extensions;
+
+/* 
+ * Provider specific attribute strings for extension support 
+ *   returned with dat_ia_query() and 
+ *   DAT_PROVIDER_ATTR_MASK == DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR
+ *
+ *   DAT_NAMED_ATTR    name == extended operations and version, 
+ *               value == TRUE if extended operation is supported 
+ *               version_value = version number of extension API
+ */
+#define DAT_EXTENSION_ATTR               "DAT_EXTENSION_INTERFACE"
+#define DAT_EXTENSION_ATTR_VERSION       "DAT_EXTENSION_VERSION"
+#define DAT_EXTENSION_ATTR_FETCH_AND_ADD "DAT_EXTENSION_FETCH_AND_ADD"
+#define DAT_EXTENSION_ATTR_CMP_AND_SWAP        "DAT_EXTENSION_CMP_AND_SWAP"
+#define DAT_EXTENSION_ATTR_TRUE                "TRUE"
+#define DAT_EXTENSION_ATTR_FALSE         "FALSE"
+#define DAT_EXTENSION_ATTR_VERSION_VALUE "2.0.1"
+
+
+/* 
+ * DTO Extension OPERATIONS supported 
+ */
+typedef enum dat_dto_extension_op
+{
+     DAT_DTO_EXTENSION_FETCH_AND_ADD,
+     DAT_DTO_EXTENSION_CMP_AND_SWAP
+
+} DAT_DTO_EXTENSION_OP;
+
+
+/* 
+ * Definitions for extension subtype RETURN codes
+ *
+ * All DAT return codes are now a 4-way tuple with an 8-bit 
+ * EXTENSION_SUBTYPE reserved to cover specific extension subtypes:
+ *
+ * type: CLASS    RETURN_TYPE   EXTENSION_SUBTYPE     SUBTYPE
+ * bits: 31-30    29-16         15-8                  7-0
+ *
+ * +-------------------------------------------------------------------------+
+ * |3130 | 2928272625242322212019181716 | 15141312111009080 | 706054003020100|
+ * |CLAS | DAT_TYPE_STATUS              | EXTENSION_SUBTYPE | SUBTYPE        |
+ * +-------------------------------------------------------------------------+
+ */
+typedef enum dat_return_extension_subtype
+{
+     /* NEW extension subtypes */
+     DAT_EXTENSION_ERR_1 = DAT_SUBTYPE_MASK+1,
+     DAT_EXTENSION_ERR_2,
+     DAT_EXTENSION_ERR_3
+
+} DAT_RETURN_EXTENSION_SUBTYPE;
+
+/* DAT_RETURN extension error to string */
+static __inline__ DAT_RETURN 
+dat_strerror_extension (
+    IN  DAT_RETURN           value,
+    OUT const char           **message )
+{
+     switch( DAT_GET_EXTENSION_SUBTYPE (value) ) {
+     case 0:
+           *message = " ";
+           return DAT_SUCCESS;
+     case DAT_EXTENSION_ERR_1:
+           *message = "DAT_EXTENSION_ERR_1";
+           return DAT_SUCCESS;
+     case DAT_EXTENSION_ERR_2:
+           *message = "DAT_EXTENSION_ERR_2";
+           return DAT_SUCCESS;
+     case DAT_EXTENSION_ERR_3:
+           *message = "DAT_EXTENSION_ERR_3";
+           return DAT_SUCCESS;
+     default:
+           *message = "unknown extension error";
+           return DAT_INVALID_PARAMETER;
+     
+     }
+}
+
+/* 
+ * Definition for memory privilege extension flags.
+ * New priviledes required for new atomic DTO type extensions.
+ * New Bit definitions MUST start at DAT_MEM_PRIV_EXTENSION
+ */
+typedef enum dat_mem_priv_extension_flags
+{
+     DAT_MEM_PRIV_EXT_START = DAT_MEM_PRIV_EXTENSION,
+     DAT_MEM_PRIV_EXT_REMOTE_ATOMIC = (DAT_MEM_PRIV_EXTENSION << 1),
+     
+} DAT_MEM_PRIV_EXTENSION_FLAGS;
+
+
+/* 
+ * DTO Extension event TYPES, DTO completion
+ */
+typedef enum dat_dto_extension_status
+{
+     DAT_DTO_EXTENSION_SUCCESS,          
+     DAT_DTO_EXTENSION_ERR_GENERAL
+
+} DAT_DTO_EXTENSION_STATUS;
+
+
+/* 
+ * DTO Extension completion event DATA types
+ */
+typedef struct dat_extension_dto_data 
+{
+    DAT_UINT64   as_64;
+
+} DAT_DTO_EXTENSION_DATA;
+
+typedef struct dat_dto_extension_event_data
+{
+     DAT_DTO_EXTENSION_OP          type;
+     DAT_DTO_EXTENSION_STATUS      status;
+     union {
+           DAT_DTO_EXTENSION_DATA  data; 
+     } val;
+
+} DAT_DTO_EXTENSION_EVENT_DATA;
+
+
+/* 
+ * Extended API with redirection via DAT extension function
+ */
+
+/*
+ * This asynchronous call is modeled after the InfiniBand atomic 
+ * Fetch and Add operation. The add_value is added to the 64 bit 
+ * value stored at the remote memory location specified in remote_iov
+ * and the result is stored in the local_iov.  
+ */
+#define dat_ep_post_fetch_and_add(ep, add_val, lbuf, cookie, rbuf, flgs) \
+           dat_extension(  ep, \
+                       DAT_DTO_EXTENSION_FETCH_AND_ADD, \
+                       (add_val), \
+                       (lbuf), \
+                       (cookie), \
+                       (rbuf), \
+                       (flgs))
+                       
+/*
+ * This asynchronous call is modeled after the InfiniBand atomic 
+ * Compare and Swap operation. The cmp_value is compared to the 64 bit 
+ * value stored at the remote memory location specified in remote_iov.  
+ * If the two values are equal, the 64 bit swap_value is stored in 
+ * the remote memory location.  In all cases, the original 64 bit 
+ * value stored in the remote memory location is copied to the local_iov.
+ */
+#define dat_ep_post_cmp_and_swap(ep, cmp_val, swap_val, lbuf, cookie, rbuf, flgs) \
+           dat_extension(  ep, \
+                       DAT_DTO_EXTENSION_CMP_AND_SWAP, \
+                       (cmp_val), \
+                       (swap_val), \
+                       (lbuf), \
+                       (cookie), \
+                       (rbuf), \
+                       (flgs))
+
+#endif /* _DAT_EXTENSIONS_H_ */
+
Index: dat/common/dat_api.c
===================================================================
--- dat/common/dat_api.c      (revision 5065)
+++ dat/common/dat_api.c      (working copy)
@@ -2,27 +2,27 @@
  * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
  *
  * This Software is licensed under one of the following licenses:
- *
+ * 
  * 1) under the terms of the "Common Public License 1.0" a copy of which is
  *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
+ *    available from the Open Source Initiative, see 
  *    http://www.opensource.org/licenses/cpl.php.
- *
+ * 
  * 2) under the terms of the "The BSD License" a copy of which is in the file
  *    LICENSE2.txt in the root directory. The license is also available from
  *    the Open Source Initiative, see
  *    http://www.opensource.org/licenses/bsd-license.php.
- *
+ * 
  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
  *    copy of which is in the file LICENSE3.txt in the root directory. The
  *    license is also available from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/gpl-license.php.
- *
+ * 
  * Licensee has the right to choose one of the above licenses.
- *
+ * 
  * Redistributions of source code must retain the above copyright
  * notice and one of the license notices.
- *
+ * 
  * Redistributions in binary form must reproduce both the above copyright
  * notice, one of the license notices in the documentation
  * and/or other materials provided with the distribution.
@@ -35,7 +35,7 @@
  * PURPOSE: DAT Provider and Consumer registry functions.
  *       Also provide small integers for IA_HANDLES
  *
- * $Id: dat_api.c,v 1.10 2005/05/20 22:25:31 jlentini Exp $
+ * $Id: dat_api.c,v 1.5 2005/02/17 19:36:23 jlentini Exp $
  **********************************************************************/
 
 #include "dat_osd.h"
@@ -70,15 +70,16 @@ dats_handle_vector_init ( void )
 {
     DAT_RETURN         dat_status;
     int                i;
+    int                status;
 
     dat_status = DAT_SUCCESS;
 
     g_hv.handle_max   = DAT_HANDLE_ENTRY_STEP;
 
-    dat_status = dat_os_lock_init (&g_hv.handle_lock);
-    if ( DAT_SUCCESS != dat_status )
+    status = dat_os_lock_init (&g_hv.handle_lock);
+    if ( DAT_SUCCESS != status )
     {
-     return dat_status;
+     return status;
     }
 
     g_hv.handle_array = dat_os_alloc (sizeof(void *) * DAT_HANDLE_ENTRY_STEP);
@@ -88,7 +89,7 @@ dats_handle_vector_init ( void )
      goto bail;
     }
 
-    for (i = 0; i < g_hv.handle_max; i++)
+    for (i = g_hv.handle_max; i < g_hv.handle_max; i++)
     {
      g_hv.handle_array[i] = NULL;
     }
@@ -112,11 +113,7 @@ dats_set_ia_handle (
     void      **h;
 
     dat_os_lock (&g_hv.handle_lock);
-
-    /*
-     * Don't give out handle zero since that is DAT_HANDLE_NULL!
-     */
-    for (i = 1; i < g_hv.handle_max; i++)
+    for (i = 0; i < g_hv.handle_max; i++)
     {
      if (g_hv.handle_array[i] == NULL)
      {
@@ -1142,6 +1139,105 @@ DAT_RETURN dat_srq_set_lw(
                     low_watermark);
 }
 
+#ifdef DAT_IMMEDIATE_DATA
+DAT_RETURN dat_ep_post_rdma_write_immed (
+     IN      DAT_EP_HANDLE         ep_handle,
+     IN      DAT_COUNT       num_segments,
+     IN      DAT_LMR_TRIPLET       *local_iov,
+     IN      DAT_DTO_COOKIE        user_cookie,
+     IN      const DAT_RMR_TRIPLET *remote_iov,
+     IN    DAT_UINT32        immed_data,
+     IN    DAT_DTO_FLAGS           dto_flags,
+     IN      DAT_COMPLETION_FLAGS  completion_flags)
+{
+    if (ep_handle == NULL)
+    {
+     return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+    }
+    return DAT_EP_POST_RDMA_WRITE_IMMED(ep_handle,
+                             num_segments,
+                             local_iov,
+                             user_cookie,
+                             remote_iov,
+                             immed_data,
+                             dto_flags,
+                             completion_flags);
+}
+
+DAT_RETURN dat_ep_post_send_immed (
+     IN      DAT_EP_HANDLE         ep_handle,
+     IN      DAT_COUNT       num_segments,
+     IN      DAT_LMR_TRIPLET       *local_iov,
+     IN      DAT_DTO_COOKIE        user_cookie,
+     IN    DAT_UINT32        immed_data,
+     IN    DAT_DTO_FLAGS           dto_flags,
+     IN      DAT_COMPLETION_FLAGS  completion_flags)
+{
+    if (ep_handle == NULL)
+    {
+     return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+    }
+    return DAT_EP_POST_SEND_IMMED (ep_handle,
+                          num_segments,
+                          local_iov,
+                          user_cookie,
+                          immed_data,
+                          dto_flags,
+                          completion_flags);
+}
+
+DAT_RETURN dat_ep_post_recv_immed (
+     IN      DAT_EP_HANDLE         ep_handle,
+     IN      DAT_COUNT       num_segments,
+     IN      DAT_LMR_TRIPLET       *local_iov,
+     IN      DAT_DTO_COOKIE        user_cookie,
+     IN      DAT_COMPLETION_FLAGS  completion_flags)
+{
+    if (ep_handle == NULL)
+    {
+     return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+    }
+    return DAT_EP_POST_RECV_IMMED (ep_handle,
+                          num_segments,
+                          local_iov,
+                          user_cookie,
+                          completion_flags);
+}
+#endif  
+
+#ifdef DAT_EXTENSIONS
+DAT_RETURN dat_extension(
+     IN    DAT_HANDLE        handle,
+     IN      DAT_DTO_EXTENSION_OP  ext_op,
+     IN    ... ) 
+     
+{
+     DAT_RETURN status;
+     va_list args;
+
+     if (handle == NULL)
+     {
+     return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
+     }
+
+     /* verify provider extension support */
+     if (!dat_extensions)
+     {
+     return DAT_ERROR(DAT_NOT_IMPLEMENTED, 0);
+     }
+
+     va_start(args, ext_op);
+
+     status = DAT_EXTENSION(handle, 
+                     ext_op,
+                     args);
+     va_end(args);
+
+     return status;
+}
+#endif 
+
+
 /*
  * Local variables:
  *  c-indent-level: 4
Index: dat/udat/Makefile
===================================================================
--- dat/udat/Makefile   (revision 5065)
+++ dat/udat/Makefile   (working copy)
@@ -112,6 +112,13 @@ CFLAGS32 = -m32
 endif
 
 #
+# Prototype 2.0 DAT extensions and immediate data 
+#
+CFLAGS += -DDAT_EXTENSIONS
+CFLAGS += -DDAT_IMMEDIATE_DATA
+
+
+#
 # LD definitions
 #
 
Index: dat/udat/udat.c
===================================================================
--- dat/udat/udat.c     (revision 5065)
+++ dat/udat/udat.c     (working copy)
@@ -2,27 +2,27 @@
  * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
  *
  * This Software is licensed under one of the following licenses:
- *
+ * 
  * 1) under the terms of the "Common Public License 1.0" a copy of which is
  *    in the file LICENSE.txt in the root directory. The license is also
- *    available from the Open Source Initiative, see
+ *    available from the Open Source Initiative, see 
  *    http://www.opensource.org/licenses/cpl.php.
- *
+ * 
  * 2) under the terms of the "The BSD License" a copy of which is in the file
  *    LICENSE2.txt in the root directory. The license is also available from
  *    the Open Source Initiative, see
  *    http://www.opensource.org/licenses/bsd-license.php.
- *
- * 3) under the terms of the "GNU General Public License (GPL) Version 2" a 
- *    copy of which is in the file LICENSE3.txt in the root directory. The 
+ * 
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is in the file LICENSE3.txt in the root directory. The
  *    license is also available from the Open Source Initiative, see
  *    http://www.opensource.org/licenses/gpl-license.php.
- *
+ * 
  * Licensee has the right to choose one of the above licenses.
- *
+ * 
  * Redistributions of source code must retain the above copyright
  * notice and one of the license notices.
- *
+ * 
  * Redistributions in binary form must reproduce both the above copyright
  * notice, one of the license notices in the documentation
  * and/or other materials provided with the distribution.
@@ -34,7 +34,7 @@
  *
  * PURPOSE: DAT Provider and Consumer registry functions.
  *
- * $Id: udat.c,v 1.22 2005/03/24 05:58:35 jlentini Exp $
+ * $Id: udat.c,v 1.20 2005/02/11 20:17:05 jlentini Exp $
  **********************************************************************/
 
 #include <dat/udat.h>
@@ -66,6 +66,10 @@ udat_check_state ( void );
  *                                                                   *
  *********************************************************************/
 
+/*
+ *  Use a global to get an unresolved when run with pre-extension library
+ */
+int dat_extensions = 0;
 
 /*
  *
@@ -226,17 +230,48 @@ dat_ia_openv (
      return dat_status;
     }
 
-    dat_status = (*ia_open_func) (name,
-                         async_event_qlen,
-                         async_event_handle,
-                         ia_handle);
+    dat_status =  (*ia_open_func) (name,
+                          async_event_qlen,
+                          async_event_handle,
+                          ia_handle);
+
+    /*
+     *  See if provider supports extensions
+     */
     if (dat_status == DAT_SUCCESS)
     {
+     DAT_PROVIDER_ATTR p_attr;
+     int               i;
+
      return_handle = dats_set_ia_handle (*ia_handle);
      if (return_handle >= 0)
      {
          *ia_handle = (DAT_IA_HANDLE)return_handle;
-     }
+     } 
+
+    if ( dat_ia_query( *ia_handle,
+                    NULL,
+                    0,
+                    NULL,
+                    DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR,
+                    &p_attr ) == DAT_SUCCESS )
+    {
+         for ( i = 0; i < p_attr.num_provider_specific_attr; i++ )
+         {
+           if ( (strcmp( p_attr.provider_specific_attr[i].name,  
+                             "DAT_EXTENSION_INTERFACE" ) == 0) &&
+                (strcmp( p_attr.provider_specific_attr[i].value, 
+                             "TRUE" ) == 0) )
+           {
+                 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
+                             "DAT Registry: dat_ia_open () "
+                             "DAPL Extension Interface supported!\n");
+
+                 dat_extensions = 1;
+                 break;
+           }
+         }
+    }
     }
 
     return dat_status;
 

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/general/attachments/20060118/c782db72/attachment.html>


More information about the general mailing list