components/open-fabrics/libibverbs/patches/base.patch
author boris.chiu@oracle.com
Mon, 03 Nov 2014 13:22:00 -0800
changeset 2187 391c8a50fa82
parent 1566 d1c87d1ecd13
child 4661 353f8a998732
permissions -rw-r--r--
19187537 iberror() of open-fabrics dumps core because of buffer overrun 19195181 wrong handling of getaddrinfo() retval in open-fabrics dumps core 19448949 libibverbs cleanup incomplete

# This patch was developed in-house. Since it is Solaris-specific,
# it is not suitable for upstream.
#
diff -r -u /tmp/846623/libibverbs-1.1.4/Makefile.am libibverbs-1.1.4/Makefile.am
--- /tmp/846623/libibverbs-1.1.4/Makefile.am	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/Makefile.am	Fri Feb 11 04:02:12 2011
@@ -4,13 +4,13 @@
 
 AM_CFLAGS = -g -Wall -D_GNU_SOURCE
 
-src_libibverbs_la_CFLAGS = $(AM_CFLAGS) -DIBV_CONFIG_DIR=\"$(sysconfdir)/libibverbs.d\"
+src_libibverbs_la_CFLAGS = $(AM_CFLAGS) -DIBV_CONFIG_DIR=\"$(datadir)/libibverbs.d\"
 
 libibverbs_version_script = @LIBIBVERBS_VERSION_SCRIPT@
 
 src_libibverbs_la_SOURCES = src/cmd.c src/compat-1_0.c src/device.c src/init.c \
 			    src/marshall.c src/memory.c src/sysfs.c src/verbs.c \
-			    src/enum_strs.c
+			    src/enum_strs.c src/solaris_compatibility.c
 src_libibverbs_la_LDFLAGS = -version-info 1 -export-dynamic \
     $(libibverbs_version_script)
 src_libibverbs_la_DEPENDENCIES = $(srcdir)/src/libibverbs.map
@@ -37,7 +37,7 @@
 
 libibverbsinclude_HEADERS = include/infiniband/arch.h include/infiniband/driver.h \
     include/infiniband/kern-abi.h include/infiniband/opcode.h include/infiniband/verbs.h \
-    include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h
+    include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h include/infiniband/ofa_solaris.h
 
 man_MANS = man/ibv_asyncwatch.1 man/ibv_devices.1 man/ibv_devinfo.1	\
     man/ibv_rc_pingpong.1 man/ibv_uc_pingpong.1 man/ibv_ud_pingpong.1	\
@@ -65,6 +65,7 @@
 
 EXTRA_DIST = include/infiniband/driver.h include/infiniband/kern-abi.h \
     include/infiniband/opcode.h include/infiniband/verbs.h include/infiniband/marshall.h \
+	 include/infiniband/ofa_solaris.h \
     include/infiniband/sa-kern-abi.h include/infiniband/sa.h \
     src/ibverbs.h examples/pingpong.h \
     src/libibverbs.map libibverbs.spec.in $(man_MANS)
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_get_device_name.3 libibverbs-1.1.4/man/ibv_get_device_name.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_get_device_name.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_get_device_name.3	Mon Mar 28 03:11:46 2011
@@ -2,7 +2,7 @@
 .\"
 .TH IBV_GET_DEVICE_NAME 3  2006-10-31 libibverbs "Libibverbs Programmer's Manual"
 .SH "NAME"
-ibv_get_device_name \- get an RDMA device's name
+ibv_get_device_name \- get an InfiniBand device's name
 .SH "SYNOPSIS"
 .nf
 .B #include <infiniband/verbs.h>
@@ -11,7 +11,7 @@
 .fi
 .SH "DESCRIPTION"
 .B ibv_get_device_name()
-returns a human-readable name associated with the RDMA device
+returns a human-readable name associated with the InfiniBand device
 .I device\fR.
 .SH "RETURN VALUE"
 .B ibv_get_device_name()
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_attach_mcast.3 libibverbs-1.1.4/man/ibv_attach_mcast.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_attach_mcast.3	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/man/ibv_attach_mcast.3	Tue May  3 13:50:06 2011
@@ -38,9 +38,6 @@
 .SH "NOTES"
 Only QPs of Transport Service Type
 .BR IBV_QPT_UD
-or
-.BR IBV_QPT_RAW_PACKET
-may be attached to multicast groups.
 .PP
 If a QP is attached to the same multicast group multiple times, the QP will still receive a single copy of a multicast message.
 .PP
@@ -48,22 +45,6 @@
 multicast group must be sent to the subnet administrator (SA), so that
 the fabric's multicast routing is configured to deliver messages to
 the local port.
-.SH EXAMPLE
-	An example of the use of ibv_attach_mcast with RAW ETH QP:
-.nf
-
-	union ibv_gid mgid;
-
-	memset(&mgid, 0, sizeof(union ibv_gid));
-
-	memcpy(&mgid.raw[10], mmac, 6);
-
-	if (ibv_attach_mcast(qp, &mgid, 0)) {
-		printf ("Failed to attach qp to mcast. Errno: %d\\n",errno);
-		return 1;
-	}
-.fi
-
 .SH "SEE ALSO"
 .BR ibv_create_qp (3)
 .SH "AUTHORS"
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_modify_qp.3 libibverbs-1.1.4/man/ibv_modify_qp.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_modify_qp.3	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/man/ibv_modify_qp.3	Tue May  3 13:50:06 2011
@@ -161,7 +161,7 @@
 .fi
 .PP
 .nf
-For QP Transport Service Type \fB IBV_QPT_RAW_PACKET\fR:
+For QP Transport Service Type:
 .sp
 Next state     Required attributes
 \-\-\-\-\-\-\-\-\-\-     \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_devinfo.1 libibverbs-1.1.4/man/ibv_devinfo.1
--- /tmp/846623/libibverbs-1.1.4/man/ibv_devinfo.1	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_devinfo.1	Mon Mar 28 03:11:46 2011
@@ -1,7 +1,7 @@
 .TH IBV_DEVINFO 1 "August 30, 2005" "libibverbs" "USER COMMANDS"
 
 .SH NAME
-ibv_devinfo \- query RDMA devices
+ibv_devinfo \- query InfiniBand devices
 
 .SH SYNOPSIS
 .B ibv_devinfo
@@ -9,7 +9,7 @@
 
 .SH DESCRIPTION
 .PP
-Print information about RDMA devices available for use from userspace.
+Print information about InfiniBand devices available for use from userspace.
 
 .SH OPTIONS
 
@@ -22,10 +22,10 @@
 query port \fIPORT\fR (default all ports)
 
 \fB\-l\fR, \fB\-\-list\fR
-only list names of RDMA devices
+only list names of InfiniBand devices
 
 \fB\-v\fR, \fB\-\-verbose\fR
-print all available information about RDMA devices
+print all available information about InfiniBand devices
 
 .SH SEE ALSO
 .BR ibv_devices (1)
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_query_qp.3 libibverbs-1.1.4/man/ibv_query_qp.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_query_qp.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_query_qp.3	Mon Mar 28 03:11:47 2011
@@ -68,7 +68,7 @@
 The argument
 .I attr_mask
 is a hint that specifies the minimum list of attributes to retrieve.
-Some RDMA devices may return extra attributes not requested, for
+Some InfiniBand devices may return extra attributes not requested, for
 example if the value can be returned cheaply. This has the same
 form as in
 .B ibv_modify_qp()\fR.
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_get_device_guid.3 libibverbs-1.1.4/man/ibv_get_device_guid.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_get_device_guid.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_get_device_guid.3	Mon Mar 28 03:11:46 2011
@@ -2,7 +2,7 @@
 .\"
 .TH IBV_GET_DEVICE_GUID 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
 .SH "NAME"
-ibv_get_device_guid \- get an RDMA device's GUID
+ibv_get_device_guid \- get an InfiniBand device's GUID
 .SH "SYNOPSIS"
 .nf
 .B #include <infiniband/verbs.h>
@@ -11,7 +11,7 @@
 .fi
 .SH "DESCRIPTION"
 .B ibv_get_device_name()
-returns the Global Unique IDentifier (GUID) of the RDMA device
+returns the Global Unique IDentifier (GUID) of the InfiniBand device
 .I device\fR.
 .SH "RETURN VALUE"
 .B ibv_get_device_guid()
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_post_send.3 libibverbs-1.1.4/man/ibv_post_send.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_post_send.3	Thu Mar 10 06:58:20 2011
+++ libibverbs-1.1.4/man/ibv_post_send.3	Tue Nov 13 10:04:25 2012
@@ -91,14 +91,17 @@
 The attribute send_flags describes the properties of the \s-1WR\s0. It is either 0 or the bitwise \s-1OR\s0 of one or more of the following flags:
 .PP
 .TP
-.B IBV_SEND_FENCE \fR Set the fence indicator.  Valid only for QPs with Transport Service Type \fBIBV_QPT_RC
+.B IBV_SEND_FENCE \fR
+Set the fence indicator.  Valid only for QPs with Transport Service Type \fBIBV_QPT_RC
 .TP
-.B IBV_SEND_SIGNALED \fR Set the completion notification indicator.  Relevant only if QP was created with sq_sig_all=0
+.B IBV_SEND_SIGNALED \fR
+Set the completion notification indicator.  Relevant only if QP was created with sq_sig_all=0
 .TP
-.B IBV_SEND_SOLICITED \fR Set the solicited event indicator.  Valid only for Send and RDMA Write with immediate
+.B IBV_SEND_SOLICITED \fR
+Set the solicited event indicator.  Valid only for Send and RDMA Write with immediate
 .TP
-.B IBV_SEND_INLINE \fR Send data in given gather list as inline data
-in a send WQE.  Valid only for Send and RDMA Write.  The L_Key will not be checked.
+.B IBV_SEND_INLINE \fR
+Send data in given gather list as inline data in a send WQE.  Valid only for Send and RDMA Write.  The L_Key will not be checked.
 .SH "RETURN VALUE"
 .B ibv_post_send()
 returns 0 on success, or the value of errno on failure (which indicates the failure reason).
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_alloc_pd.3 libibverbs-1.1.4/man/ibv_alloc_pd.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_alloc_pd.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_alloc_pd.3	Mon Mar 28 03:11:45 2011
@@ -13,7 +13,7 @@
 .fi
 .SH "DESCRIPTION"
 .B ibv_alloc_pd()
-allocates a PD for the RDMA device context 
+allocates a PD for the InfiniBand device context 
 .I context\fR.
 .PP
 .B ibv_dealloc_pd()
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_get_async_event.3 libibverbs-1.1.4/man/ibv_get_async_event.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_get_async_event.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_get_async_event.3	Mon Mar 28 03:11:46 2011
@@ -14,7 +14,7 @@
 .fi
 .SH "DESCRIPTION"
 .B ibv_get_async_event()
-waits for the next async event of the RDMA device context
+waits for the next async event of the InfiniBand device context
 .I context
 and returns it through the pointer
 .I event\fR,
@@ -29,6 +29,8 @@
 struct ibv_qp  *qp;             /* QP that got the event */
 struct ibv_srq *srq;            /* SRQ that got the event */
 int             port_num;       /* port number that got the event */
+uint32_t        xrc_qp_num;     /* XRC QP that got the event */
+union ibv_gid   gid;            /* list of guids that got the event */
 .in -8
 } element;
 enum ibv_event_type     event_type;     /* type of the event */
@@ -86,6 +88,16 @@
 .TP
 .B IBV_EVENT_DEVICE_FATAL \fR CA is in FATAL state
 .PP
+.I Subnet events:
+.TP
+.B IBV_SM_EVENT_MCG_CREATED \fR notification of MCG creation
+.TP
+.B IBV_SM_EVENT_MCG_DELETED \fR notification of MCG deletion
+.TP
+.B IBV_SM_EVENT_GID_AVAIL \fR notification of GID available events
+.TP
+.B IBV_SM_EVENT_GID_UNAVAIL \fR notification of GID unavailable events
+.PP
 .B ibv_ack_async_event()
 acknowledge the async event
 .I event\fR.
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_get_device_list.3 libibverbs-1.1.4/man/ibv_get_device_list.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_get_device_list.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_get_device_list.3	Mon Mar 28 03:11:46 2011
@@ -2,7 +2,7 @@
 .\"
 .TH IBV_GET_DEVICE_LIST 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
 .SH "NAME"
-ibv_get_device_list, ibv_free_device_list \- get and release list of available RDMA devices
+ibv_get_device_list, ibv_free_device_list \- get and release list of available InfiniBand devices
 .SH "SYNOPSIS"
 .nf
 .B #include <infiniband/verbs.h>
@@ -13,7 +13,7 @@
 .fi
 .SH "DESCRIPTION"
 .B ibv_get_device_list()
-returns a NULL-terminated array of RDMA devices currently available.
+returns a NULL-terminated array of InfiniBand devices currently available.
 The argument
 .I num_devices
 is optional; if not NULL, it is set to the number of devices returned in the array.
@@ -25,7 +25,7 @@
 .B ibv_get_device_list()\fR.
 .SH "RETURN VALUE"
 .B ibv_get_device_list()
-returns the array of available RDMA devices, or sets
+returns the array of available InfiniBand devices, or sets
 .I errno
 and returns NULL if the request fails. If no devices are found then
 .I num_devices
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_query_device.3 libibverbs-1.1.4/man/ibv_query_device.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_query_device.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_query_device.3	Mon Mar 28 03:11:47 2011
@@ -2,7 +2,7 @@
 .\"
 .TH IBV_QUERY_DEVICE 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
 .SH "NAME"
-ibv_query_device \- query an RDMA device's attributes
+ibv_query_device \- query an InfiniBand device's attributes
 .SH "SYNOPSIS"
 .nf
 .B #include <infiniband/verbs.h>
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_query_port.3 libibverbs-1.1.4/man/ibv_query_port.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_query_port.3	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/man/ibv_query_port.3	Mon Mar 28 03:11:47 2011
@@ -2,7 +2,7 @@
 .\"
 .TH IBV_QUERY_PORT 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
 .SH "NAME"
-ibv_query_port \- query an RDMA port's attributes
+ibv_query_port \- query an InfiniBand port's attributes
 .SH "SYNOPSIS"
 .nf
 .B #include <infiniband/verbs.h>
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_asyncwatch.1 libibverbs-1.1.4/man/ibv_asyncwatch.1
--- /tmp/846623/libibverbs-1.1.4/man/ibv_asyncwatch.1	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_asyncwatch.1	Mon Mar 28 03:11:45 2011
@@ -1,16 +1,78 @@
-.TH IBV_ASYNCWATCH 1 "August 30, 2005" "libibverbs" "USER COMMANDS"
+'\" te
+.TH IBV_ASYNCWATCH 1 "August 8, 2012" "libibverbs" "USER COMMANDS"
 
 .SH NAME
 ibv_asyncwatch \- display asynchronous events
 
 .SH SYNOPSIS
-.B ibv_asyncwatch
-
+.sp
+.nf
+\fIibv_asyncwatch\fR [\-G | \-M] [\-s[<guid>]] [\-p port]
+\fIibv_asyncwactch\fR \-s
+\fIibv_asyncwatch\fR \-G \-s
+\fIibv_asyncwatch\fR \-M \-s
+\fIibv_asyncwatch\fR \-G [\-p port] \-s<guid1>,<guid2>,...
+\fIibv_asyncwatch\fR \-M [\-p port] \-s<mgid1>,<mgid2>,...
+.fi
+.sp
 .SH DESCRIPTION
 .PP
-Display asynchronous events forwarded to userspace for an RDMA device.
+Display asynchronous events forwarded to userspace for an InfiniBand device.
+SM events can be monitored using the '-s' option, which optionally
+takes a remote port GUID, or list of remote port GUIDS separated by ','.
+If '-s' is specified with no argument then all remote nodes reachable
+form device 0 are monitored, otherwise only the specified remote
+nodes are monitored. The following SM events are monitored using
+the '-s' option: 
 
-.SH AUTHORS
-.TP
-Roland Dreier
-.RI < [email protected] >
+    IBV_SM_EVENT_MCG_CREATED
+         An MCG specified by the "mgid" has been created
+         on this subnet.
+
+    IBV_SM_EVENT_MCG_DELETED
+         The MCG specified by the "mgid" has been deleted
+         on this subnet.
+
+    IBV_SM_EVENT_GID_AVAIL
+         The GID specified by the "guid" is available
+         on this subnet.
+
+    IBV_SM_EVENT_GID_UNAVAIL
+         The GID specified by the "guid" is no longer
+         available on this subnet.
+
+.SH OPTIONS
+.pp
+\-G               Monitor SM event for Unicast GIDs
+.sp
+.pp
+\-M               Monitor SM event for Multicast GIDs
+.pp
+\-s<GUID>         Takes as an optional argument a comma separated list of remote port GUIDs if \-G is specified or Multicast GIDs if \-M is specified.
+.sp
+.PP
+\-p <port>        use the specified ca_port.
+.sp
+.pp
+.SH EXAMPLES
+.PP
+To monitor event=IBV_SM_EVENT_ALL
+.sp
+ibv_asyncwatch -s
+.sp
+To monitor event=IBV_SM_EVENT_UGID_ALL
+.sp
+ibv_asyncwatch -G -s
+.sp
+To monitor event=IBV_SM_EVENT_MGID_ALL
+.sp
+ibv_asyncwatch -M -s
+.sp
+To monitor event=IBV_SM_EVENT_UGID
+.sp
+ibv_asyncwatch -G -s0x0021280001a0e4d9,0x0021280001a0e4da
+.sp
+To monitor event=IBV_SM_EVENT_MGID
+.sp
+ibv_asyncwatch -M -s0xff12:4001:ffff::c:2238
+.sp
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_open_device.3 libibverbs-1.1.4/man/ibv_open_device.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_open_device.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_open_device.3	Mon Mar 28 03:11:46 2011
@@ -2,7 +2,7 @@
 .\"
 .TH IBV_OPEN_DEVICE 3 2006-10-31 libibverbs "Libibverbs Programmer's Manual"
 .SH "NAME"
-ibv_open_device, ibv_close_device \- open and close an RDMA device context
+ibv_open_device, ibv_close_device \- open and close an InfiniBand device context
 .SH "SYNOPSIS"
 .nf
 .B #include <infiniband/verbs.h>
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_create_comp_channel.3 libibverbs-1.1.4/man/ibv_create_comp_channel.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_create_comp_channel.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_create_comp_channel.3	Mon Mar 28 03:11:45 2011
@@ -15,7 +15,7 @@
 .fi
 .SH "DESCRIPTION"
 .B ibv_create_comp_channel()
-creates a completion event channel for the RDMA device context
+creates a completion event channel for the InfiniBand device context
 .I context\fR.
 .PP
 .B ibv_destroy_comp_channel()
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_create_cq.3 libibverbs-1.1.4/man/ibv_create_cq.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_create_cq.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_create_cq.3	Mon Mar 28 03:11:45 2011
@@ -18,7 +18,7 @@
 .B ibv_create_cq()
 creates a completion queue (CQ) with at least
 .I cqe
-entries for the RDMA device context
+entries for the InfiniBand device context
 .I context\fR.
 The pointer
 .I cq_context
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_devices.1 libibverbs-1.1.4/man/ibv_devices.1
--- /tmp/846623/libibverbs-1.1.4/man/ibv_devices.1	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_devices.1	Mon Mar 28 03:11:45 2011
@@ -1,7 +1,7 @@
 .TH IBV_DEVICES 1 "August 30, 2005" "libibverbs" "USER COMMANDS"
 
 .SH NAME
-ibv_devices \- list RDMA devices
+ibv_devices \- list InfiniBand devices
 
 .SH SYNOPSIS
 .B ibv_devices
@@ -8,8 +8,37 @@
 
 .SH DESCRIPTION
 .PP
-List RDMA devices available for use from userspace.
+List InfiniBand devices available for use from userspace.
 
+On SR-IOV capable systems, if a domain is configured with
+VFs (Virtual Function), ibv_devices lists for each IB device
+the node GUID and the type (PF or VF).  In this case, the PF
+devices are displayed before the VF devices.  The following
+shows the results of running ibv_devices on a domain with
+one PF and two VFs:
+
+    device                 node GUID            type
+    ------              ----------------        ----
+    mlx4_2              00212800013f3126         PF
+    mlx4_0              00212d00013f3126         VF
+    mlx4_1              00212900013f3126         VF
+
+If all of the IB devices are PFs, only node GUIDs are
+listed.  The following shows the results of running
+ibv_devices on a domain with one PF and no VFs:
+
+    device                 node GUID
+    ------              ----------------
+    mlx4_0              00212800013f3126
+
+On systems which are not SR-IOV capable only node GUIDs are
+listed.
+
+    device                 node GUID
+    ------              ----------------
+    mlx4_0              0021280001a0e4d8
+    mlx4_1              0021280001a0e754
+
 .SH SEE ALSO
 .BR ibv_devinfo (1)
 
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_create_qp.3 libibverbs-1.1.4/man/ibv_create_qp.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_create_qp.3	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/man/ibv_create_qp.3	Tue May  3 13:50:06 2011
@@ -28,7 +28,7 @@
 struct ibv_cq          *recv_cq;        /* CQ to be associated with the Receive Queue (RQ) */
 struct ibv_srq         *srq;            /* SRQ handle if QP is to be associated with an SRQ, otherwise NULL */
 struct ibv_qp_cap       cap;            /* QP capabilities */
-enum ibv_qp_type        qp_type;        /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, IBV_QPT_UD, IBV_QPT_XRC or IBV_QPT_RAW_PACKET */
+enum ibv_qp_type        qp_type;        /* QP Transport Service Type: IBV_QPT_RC, IBV_QPT_UC, IBV_QPT_UD, IBV_QPT_XRC */
 int                     sq_sig_all;     /* If set, each Work Request (WR) submitted to the SQ generates a completion entry */
 struct ibv_xrc_domain  *xrc_domain;     /* XRC domain the QP will be associated with (valid only for IBV_QPT_XRC QP), otherwise NULL */
 .in -8
diff -r -u /tmp/846623/libibverbs-1.1.4/man/ibv_create_ah_from_wc.3 libibverbs-1.1.4/man/ibv_create_ah_from_wc.3
--- /tmp/846623/libibverbs-1.1.4/man/ibv_create_ah_from_wc.3	Thu Mar 10 04:51:46 2011
+++ libibverbs-1.1.4/man/ibv_create_ah_from_wc.3	Mon Mar 28 03:11:45 2011
@@ -21,7 +21,7 @@
 .B ibv_init_ah_from_wc()
 initializes the address handle (AH) attribute structure
 .I ah_attr
-for the RDMA device context
+for the InfiniBand device context
 .I context
 using the port number
 .I port_num\fR,
diff -r -u /tmp/846623/libibverbs-1.1.4/src/kern_abi.h libibverbs-1.1.4/src/kern_abi.h
--- /tmp/846623/libibverbs-1.1.4/src/kern_abi.h	Wed Sep 16 04:27:22 2009
+++ libibverbs-1.1.4/src/kern_abi.h	Fri Feb 11 04:02:32 2011
@@ -33,7 +33,11 @@
 #ifndef KERN_ABI_H
 #define KERN_ABI_H
 
+#if !(defined(__SVR4) && defined(__sun))
 #include <linux/types.h>
+#else
+#include <infiniband/ofa_solaris.h>
+#endif
 
 /*
  * Increment this value if any changes that break userspace ABI
@@ -47,7 +51,10 @@
 	IB_USER_VERBS_CMD_ALLOC_PD,
 	IB_USER_VERBS_CMD_DEALLOC_PD,
 	IB_USER_VERBS_CMD_REG_MR,
-	IB_USER_VERBS_CMD_DEREG_MR
+	IB_USER_VERBS_CMD_DEREG_MR,
+	IB_USER_VERBS_CMD_REG_MR_RELAXED,
+	IB_USER_VERBS_CMD_DEREG_MR_RELAXED,
+	IB_USER_VERBS_CMD_FLUSH_RELAXED_MR
 };
 
 /*
diff -r -u /tmp/846623/libibverbs-1.1.4/src/verbs.c libibverbs-1.1.4/src/verbs.c
--- /tmp/846623/libibverbs-1.1.4/src/verbs.c	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/src/verbs.c	Fri Feb 11 04:02:33 2011
@@ -41,9 +41,24 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#if defined(__SVR4) && defined(__sun)
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mkdev.h>
+#endif
 
 #include "ibverbs.h"
 
+#define	IBV_IS_VALID_UGID(gid)	\
+	(gid->raw[0] != 0xff)
+
+#define	IBV_IS_VALID_MGID(gid)					\
+	((gids->raw[0] == 0xff) &&				\
+	((gids->raw[1] == 0x0e) || (gids->raw[1] == 0x02) ||	\
+	(gids->raw[1] == 0x05)  || (gids->raw[1] == 0x08) ||	\
+	(gids->raw[1] == 0x1e)  || (gids->raw[1] == 0x12) ||	\
+	(gids->raw[1] == 0x15)  || (gids->raw[1] == 0x18)))
+
 int ibv_rate_to_mult(enum ibv_rate rate)
 {
 	switch (rate) {
@@ -93,6 +108,12 @@
 int __ibv_query_gid(struct ibv_context *context, uint8_t port_num,
 		    int index, union ibv_gid *gid)
 {
+#if defined(__SVR4) && defined(__sun)
+	extern int sol_ibv_query_gid();
+
+	return sol_ibv_query_gid(context, port_num, index, gid);
+
+#else
 	char name[24];
 	char attr[41];
 	uint16_t val;
@@ -112,6 +133,7 @@
 	}
 
 	return 0;
+#endif
 }
 default_symver(__ibv_query_gid, ibv_query_gid);
 
@@ -118,6 +140,12 @@
 int __ibv_query_pkey(struct ibv_context *context, uint8_t port_num,
 		     int index, uint16_t *pkey)
 {
+#if defined(__SVR4) && defined(__sun)
+	extern int sol_ibv_query_pkey();
+
+	return sol_ibv_query_pkey(context, port_num, index, pkey);
+
+#else
 	char name[24];
 	char attr[8];
 	uint16_t val;
@@ -133,9 +161,159 @@
 
 	*pkey = htons(val);
 	return 0;
+#endif
 }
 default_symver(__ibv_query_pkey, ibv_query_pkey);
 
+int ibv_register_sm_events(struct ibv_context *context,
+    ibv_sm_event_type_t event, uint_t gid_num, union ibv_gid *gids)
+{
+	struct ibv_reg_sm_event		*cmd;
+	int				cmd_size, data_size;
+	void				*data_p;
+
+	if (((gid_num > 0) && (gids == NULL)) ||
+	   ((gid_num == 0) && (gids != NULL))) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if ((event != IBV_SM_EVENT_UGID) && (event != IBV_SM_EVENT_UGID_ALL) &&
+	    (event != IBV_SM_EVENT_MGID) && (event != IBV_SM_EVENT_MGID_ALL) &&
+	    (event != IBV_SM_EVENT_ALL)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (((event == IBV_SM_EVENT_UGID) || (event == IBV_SM_EVENT_MGID)) &&
+	    (gid_num == 0)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (((event == IBV_SM_EVENT_UGID_ALL) ||
+	    (event == IBV_SM_EVENT_MGID_ALL) || (event == IBV_SM_EVENT_ALL)) &&
+	    (gid_num != 0)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	data_size = gid_num * (sizeof (union ibv_gid));
+	cmd_size = (sizeof (struct ibv_reg_sm_event)) + data_size;
+	data_p = (void *)gids;
+	cmd  = alloca(cmd_size);
+	cmd->data_num = gid_num;
+
+	if ((event == IBV_SM_EVENT_UGID) && (!IBV_IS_VALID_UGID(gids))) { 
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if ((event == IBV_SM_EVENT_MGID) && (!IBV_IS_VALID_MGID(gids))) { 
+		errno = EINVAL;
+		return (-1);
+	}
+
+	IBV_INIT_CMD(cmd, cmd_size, REG_SM_EVENT);
+
+	cmd->events = event;
+	if (gid_num > 0)
+		memcpy(cmd->driver_data, data_p, data_size);
+
+	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	return (0);
+}
+
+int ibv_unregister_sm_events(struct ibv_context *context,
+    ibv_sm_event_type_t event, uint_t gid_num, union ibv_gid *gids)
+{
+	struct ibv_unreg_sm_event	*cmd;
+	int				cmd_size, data_size;
+	void				*data_p;
+
+	if (((gid_num > 0) && (gids == NULL)) ||
+	   ((gid_num == 0) && (gids != NULL))) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if ((event != IBV_SM_EVENT_UGID) && (event != IBV_SM_EVENT_UGID_ALL) &&
+	    (event != IBV_SM_EVENT_MGID) && (event != IBV_SM_EVENT_MGID_ALL) &&
+	    (event != IBV_SM_EVENT_ALL)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (((event == IBV_SM_EVENT_UGID) || (event == IBV_SM_EVENT_MGID)) &&
+	    (gid_num == 0)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (((event == IBV_SM_EVENT_UGID_ALL) ||
+	    (event == IBV_SM_EVENT_MGID_ALL) || (event == IBV_SM_EVENT_ALL)) &&
+	    (gid_num != 0)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	data_size = gid_num*(sizeof (union ibv_gid));
+	cmd_size = (sizeof (struct ibv_unreg_sm_event)) + data_size;
+	data_p = (void *)gids;
+	cmd  = alloca(cmd_size);
+	cmd->data_num = gid_num;
+
+	if ((event == IBV_SM_EVENT_UGID) && (!IBV_IS_VALID_UGID(gids))) { 
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if ((event == IBV_SM_EVENT_MGID) && (!IBV_IS_VALID_MGID(gids))) { 
+		errno = EINVAL;
+		return (-1);
+	}
+
+	IBV_INIT_CMD(cmd, cmd_size, UNREG_SM_EVENT);
+
+	cmd->events = event;
+	if (gid_num > 0)
+		memcpy(cmd->driver_data, data_p, data_size);
+
+	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	return (0);
+}
+
+int ibv_gid_reachable(struct ibv_context *context,
+    uint_t port, union ibv_gid *gid_p, int timeout)
+{
+	struct ibv_gid_reachable	*cmd;
+	int				rc;
+
+	cmd = alloca((sizeof (struct ibv_gid_reachable)));
+	cmd->port_num = port;
+	cmd->timeout = timeout;
+
+	IBV_INIT_CMD(cmd, sizeof (struct ibv_gid_reachable),
+	    GID_REACHABLE);
+
+	memcpy(cmd->gid, gid_p, sizeof (*gid_p));
+
+	rc = write(context->cmd_fd, cmd, sizeof(struct ibv_gid_reachable));
+	if (rc < 0) {
+		return (-1);
+	}
+
+	return (0);
+}
+
 struct ibv_pd *__ibv_alloc_pd(struct ibv_context *context)
 {
 	struct ibv_pd *pd;
@@ -148,6 +326,27 @@
 }
 default_symver(__ibv_alloc_pd, ibv_alloc_pd);
 
+struct ibv_shpd *__ibv_alloc_shpd(struct ibv_pd *pd, uint64_t share_key, struct ibv_shpd *shpd)
+{
+
+	shpd = pd->context->ops.alloc_shpd(pd, share_key, shpd);
+
+	return shpd;
+}
+default_symver(__ibv_alloc_shpd, ibv_alloc_shpd);
+
+struct ibv_pd *__ibv_share_pd(struct ibv_context *context, struct ibv_shpd *shpd, uint64_t share_key)
+{
+	struct ibv_pd *pd;
+
+	pd = context->ops.share_pd(context, shpd, share_key);
+	if (pd)
+		pd->context = context;
+
+	return pd;
+}
+default_symver(__ibv_share_pd, ibv_share_pd);
+
 int __ibv_dealloc_pd(struct ibv_pd *pd)
 {
 	return pd->context->ops.dealloc_pd(pd);
@@ -175,6 +374,27 @@
 }
 default_symver(__ibv_reg_mr, ibv_reg_mr);
 
+struct ibv_mr *__ibv_reg_mr_relaxed(struct ibv_pd *pd, void *addr,
+			    size_t length, int access)
+{
+	struct ibv_mr *mr;
+
+	if (ibv_dontfork_range(addr, length))
+		return NULL;
+
+	mr = pd->context->ops.reg_mr_relaxed(pd, addr, length, access);
+	if (mr) {
+		mr->context = pd->context;
+		mr->pd      = pd;
+		mr->addr    = addr;
+		mr->length  = length;
+	} else
+		ibv_dofork_range(addr, length);
+
+	return mr;
+}
+default_symver(__ibv_reg_mr_relaxed, ibv_reg_mr_relaxed);
+
 int __ibv_dereg_mr(struct ibv_mr *mr)
 {
 	int ret;
@@ -189,6 +409,26 @@
 }
 default_symver(__ibv_dereg_mr, ibv_dereg_mr);
 
+int __ibv_dereg_mr_relaxed(struct ibv_mr *mr)
+{
+	int ret;
+	void *addr	= mr->addr;
+	size_t length	= mr->length;
+
+	ret = mr->context->ops.dereg_mr_relaxed(mr);
+	if (!ret)
+		ibv_dofork_range(addr, length);
+
+	return ret;
+}
+default_symver(__ibv_dereg_mr_relaxed, ibv_dereg_mr_relaxed);
+
+int __ibv_flush_relaxed_mr(struct ibv_pd *pd)
+{
+	return pd->context->ops.flush_relaxed_mr(pd);
+}
+default_symver(__ibv_flush_relaxed_mr, ibv_flush_relaxed_mr);
+
 static struct ibv_comp_channel *ibv_create_comp_channel_v2(struct ibv_context *context)
 {
 	struct ibv_abi_compat_v2 *t = context->abi_compat;
@@ -212,6 +452,10 @@
 	struct ibv_comp_channel            *channel;
 	struct ibv_create_comp_channel      cmd;
 	struct ibv_create_comp_channel_resp resp;
+#if defined(__SVR4) && defined(__sun)
+	int		event_fd;
+	struct stat	fstat_buf;
+#endif
 
 	if (abi_ver <= 2)
 		return ibv_create_comp_channel_v2(context);
@@ -221,7 +465,23 @@
 		return NULL;
 
 	IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_COMP_CHANNEL, &resp, sizeof resp);
+#if defined(__SVR4) && defined(__sun)
+	event_fd = open("/dev/infiniband/ofs/uverbs:event", O_RDWR);
+	if (event_fd < 0) {
+		free(channel);
+		return NULL;
+	}
+
+	if (fstat(event_fd, &fstat_buf)) {
+		free(channel);
+		return NULL;
+	}
+	resp.fd = minor(fstat_buf.st_rdev);
+#endif
 	if (write(context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) {
+#if defined(__SVR4) && defined(__sun)
+		close(event_fd);
+#endif
 		free(channel);
 		return NULL;
 	}
@@ -228,6 +488,9 @@
 
 	VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
 
+#if defined(__SVR4) && defined(__sun)
+	resp.fd = event_fd;
+#endif
 	channel->context = context;
 	channel->fd      = resp.fd;
 	channel->refcnt  = 0;
diff -r -u /tmp/846623/libibverbs-1.1.4/src/device.c libibverbs-1.1.4/src/device.c
--- /tmp/846623/libibverbs-1.1.4/src/device.c	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/src/device.c	Fri Feb 11 04:02:31 2011
@@ -122,6 +122,28 @@
 }
 default_symver(__ibv_get_device_guid, ibv_get_device_guid);
 
+uint64_t __ibv_get_device_guid_external(struct ibv_device *device)
+{
+	char attr[24];
+	uint64_t guid = 0;
+	uint16_t parts[4];
+	int i;
+
+	if (ibv_read_sysfs_file(device->ibdev_path, "node_guid_external",
+				attr, sizeof attr) < 0)
+		return 0;
+
+	if (sscanf(attr, "%hx:%hx:%hx:%hx",
+		   parts, parts + 1, parts + 2, parts + 3) != 4)
+		return 0;
+
+	for (i = 0; i < 4; ++i)
+		guid = (guid << 16) | parts[i];
+
+	return htonll(guid);
+}
+default_symver(__ibv_get_device_guid_external, ibv_get_device_guid_external);
+
 struct ibv_context *__ibv_open_device(struct ibv_device *device)
 {
 	char *devpath;
@@ -128,8 +150,13 @@
 	int cmd_fd;
 	struct ibv_context *context;
 
+#if !(defined(__SVR4) && defined(__sun))
 	if (asprintf(&devpath, "/dev/infiniband/%s", device->dev_name) < 0)
 		return NULL;
+#else
+	if (asprintf(&devpath, "/dev/infiniband/ofs/%s", device->dev_name) < 0)
+		return NULL;
+#endif		
 
 	/*
 	 * We'll only be doing writes, but we need O_RDWR in case the
@@ -141,6 +168,15 @@
 	if (cmd_fd < 0)
 		return NULL;
 
+#if defined(__SVR4) && defined(__sun)
+	/* We don't support parent-child sharing of IB resources on Solaris */
+	if (fcntl(cmd_fd, F_SETFD, FD_CLOEXEC) < 0) {
+		fprintf(stderr, "ibv_open_device: FD_CLOEXEC failed: %s\n",
+		    strerror(errno));
+		goto err;
+	}
+#endif
+
 	context = device->ops.alloc_context(device, cmd_fd);
 	if (!context)
 		goto err;
@@ -163,6 +199,9 @@
 	int async_fd = context->async_fd;
 	int cmd_fd   = context->cmd_fd;
 	int cq_fd    = -1;
+#if defined(__SVR4) && defined(__sun)
+	int mmap_fd   = context->mmap_fd;
+#endif
 
 	if (abi_ver <= 2) {
 		struct ibv_abi_compat_v2 *t = context->abi_compat;
@@ -172,6 +211,11 @@
 
 	context->device->ops.free_context(context);
 
+#if defined(__SVR4) && defined(__sun)
+	if (mmap_fd > 0) {
+		close(mmap_fd);
+	}
+#endif
 	close(async_fd);
 	close(cmd_fd);
 	if (abi_ver <= 2)
@@ -214,6 +258,15 @@
 		case IBV_EVENT_SRQ_LIMIT_REACHED:
 			event->element.srq = (void *) (uintptr_t) ev.element;
 			break;
+		case IBV_EVENT_GID_AVAIL:
+		case IBV_EVENT_GID_UNAVAIL:
+		case IBV_EVENT_MCG_CREATED:
+		case IBV_EVENT_MCG_DELETED:
+			event->element.gid.global.subnet_prefix
+			    = ev.subnet_prefix;
+                        event->element.gid.global.interface_id
+			    = ev.interface_id;
+			break;
 		default:
 			event->element.port_num = ev.element;
 			break;
diff -r -u /tmp/846623/libibverbs-1.1.4/src/ibverbs.h libibverbs-1.1.4/src/ibverbs.h
--- /tmp/846623/libibverbs-1.1.4/src/ibverbs.h	Wed Sep 16 04:27:22 2009
+++ libibverbs-1.1.4/src/ibverbs.h	Fri Feb 11 04:02:31 2011
@@ -52,7 +52,12 @@
 #  define VALGRIND_MAKE_MEM_DEFINED(addr, len)
 #endif
 
-#define HIDDEN		__attribute__((visibility ("hidden")))
+#if defined(__SVR4) && defined(__sun)
+#define	HIDDEN
+#undef HAVE_SYMVER_SUPPORT
+#else
+#define	HIDDEN		__attribute__((visibility ("hidden")))
+#endif
 
 #define INIT		__attribute__((constructor))
 #define FINI		__attribute__((destructor))
diff -r -u /tmp/846623/libibverbs-1.1.4/src/libibverbs.map libibverbs-1.1.4/src/libibverbs.map
--- /tmp/846623/libibverbs-1.1.4/src/libibverbs.map	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/src/libibverbs.map	Mon Mar 28 13:44:44 2011
@@ -12,10 +12,18 @@
 		ibv_query_port;
 		ibv_query_gid;
 		ibv_query_pkey;
+		ibv_register_sm_events;
+		ibv_unregister_sm_events;
+		ibv__gid_reachable;
 		ibv_alloc_pd;
+		ibv_alloc_shpd;
+		ibv_share_pd;
 		ibv_dealloc_pd;
 		ibv_reg_mr;
+		ibv_reg_mr_relaxed;
 		ibv_dereg_mr;
+		ibv_dereg_mr_relaxed;
+		ibv_flush_relaxed_mr;
 		ibv_create_comp_channel;
 		ibv_destroy_comp_channel;
 		ibv_create_cq;
@@ -41,9 +49,14 @@
 		ibv_cmd_query_gid;
 		ibv_cmd_query_pkey;
 		ibv_cmd_alloc_pd;
+		ibv_cmd_alloc_shpd;
+		ibv_cmd_share_pd;
 		ibv_cmd_dealloc_pd;
 		ibv_cmd_reg_mr;
+		ibv_cmd_reg_mr_relaxed;
 		ibv_cmd_dereg_mr;
+		ibv_cmd_dereg_mr_relaxed;
+		ibv_cmd_flush_relaxed_mr;
 		ibv_cmd_create_cq;
 		ibv_cmd_poll_cq;
 		ibv_cmd_req_notify_cq;
@@ -71,6 +84,7 @@
 		mult_to_ibv_rate;
 		ibv_get_sysfs_path;
 		ibv_read_sysfs_file;
+		sol_get_cpu_info;
 
 	local: *;
 };
diff -r -u /tmp/846623/libibverbs-1.1.4/src/cmd.c libibverbs-1.1.4/src/cmd.c
--- /tmp/846623/libibverbs-1.1.4/src/cmd.c	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/src/cmd.c	Fri Feb 11 04:02:31 2011
@@ -42,9 +42,34 @@
 #include <errno.h>
 #include <alloca.h>
 #include <string.h>
+#if defined(__SVR4) && defined(__sun)
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mkdev.h>
+#endif
 
 #include "ibverbs.h"
 
+#if defined(__SVR4) && defined(__sun)
+extern int ibv_open_mmap_driver(char *dev_name);
+
+/*
+ * Event file creation for GET_CONTEXT & CREATE_COMP_CHANNEL :
+ * 	Solaris Uverbs driver supports creation of event file
+ * 	from the open(2) system call only. Event file will not
+ * 	be created by the write(2) syscall, for the above commands
+ *	as in Linux OFED.
+ *
+ * Sequence of operations for GET_CONTEXT &  CREATE_COMP_CHANNEL :
+ *	event_fd = open(UVERBS_EVENT_FILE, O_RDWR);
+ *	fstat(event_fd, &fstat_buf);
+ *	NOTE : Minor number of event file passed to driver 
+ *	cmd.resp.fd = minor(fstat_buf.st_rdev);
+ *	write(verbs_fd);
+ *	NOTE : Initialize the fd to one got by opening event file
+ *	cmd.resp.fd = event_fd;
+ */
+#endif
 static int ibv_cmd_get_context_v2(struct ibv_context *context,
 				  struct ibv_get_context *new_cmd,
 				  size_t new_cmd_size,
@@ -55,6 +80,10 @@
 	struct ibv_get_context_v2 *cmd;
 	size_t cmd_size;
 	uint32_t cq_fd;
+#if defined(__SVR4) && defined(__sun)
+	int			event_fd;
+	struct stat		fstat_buf;
+#endif
 
 	t = malloc(sizeof *t);
 	if (!t)
@@ -67,12 +96,36 @@
 
 	IBV_INIT_CMD_RESP(cmd, cmd_size, GET_CONTEXT, resp, resp_size);
 	cmd->cq_fd_tab = (uintptr_t) &cq_fd;
+#if defined(__SVR4) && defined(__sun)
+	event_fd = open("/dev/infiniband/ofs/uverbs:event", O_RDWR);
+	if (event_fd < 0)
+		return (errno);	
+	if (fstat(event_fd, &fstat_buf))
+		return (errno);
+	resp->async_fd = minor(fstat_buf.st_rdev);
+#endif
 
 	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
 		return errno;
+#if defined(__SVR4) && defined(__sun)
+	resp->async_fd = event_fd;
+#endif
 
 	VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
 
+#if defined(__SVR4) && defined(__sun)
+	/* We don't support parent-child sharing of IB resources on Solaris */
+	if (fcntl(resp->async_fd, F_SETFD, FD_CLOEXEC) < 0) {
+		fprintf(stderr, "ibv_get_context: FD_CLOEXEC failed "
+		    "for async_fd: %s\n", strerror(errno));
+		return errno;
+	}
+	if (fcntl(cq_fd, F_SETFD, FD_CLOEXEC) < 0) {
+		fprintf(stderr, "ibv_get_context: FD_CLOEXEC failed "
+		    "for cq_fd: %s\n", strerror(errno));
+		return errno;
+	}
+#endif
 	context->async_fd         = resp->async_fd;
 	context->num_comp_vectors = 1;
 	t->channel.context        = context;
@@ -87,19 +140,53 @@
 			size_t cmd_size, struct ibv_get_context_resp *resp,
 			size_t resp_size)
 {
+#if defined(__SVR4) && defined(__sun)
+	int			event_fd;
+	struct stat		fstat_buf;
+#endif
 	if (abi_ver <= 2)
 		return ibv_cmd_get_context_v2(context, cmd, cmd_size, resp, resp_size);
 
 	IBV_INIT_CMD_RESP(cmd, cmd_size, GET_CONTEXT, resp, resp_size);
+#if defined(__SVR4) && defined(__sun)
+	event_fd = open("/dev/infiniband/ofs/uverbs:event", O_RDWR);
+	if (event_fd < 0)
+		return (errno);	
+	if (fstat(event_fd, &fstat_buf))
+		return (errno);
+	resp->async_fd = minor(fstat_buf.st_rdev);
+#endif
 
 	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
 		return errno;
+#if defined(__SVR4) && defined(__sun)
+	resp->async_fd = event_fd;
+#endif
 
 	VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
 
+#if defined(__SVR4) && defined(__sun)
+	/* We don't support parent-child sharing of IB resources on Solaris */
+	if (fcntl(resp->async_fd, F_SETFD, FD_CLOEXEC) < 0) {
+		fprintf(stderr, "ibv_get_context: FD_CLOEXEC failed: %s\n",
+		    strerror(errno));
+		return errno;
+	}
+#endif
+
 	context->async_fd         = resp->async_fd;
 	context->num_comp_vectors = resp->num_comp_vectors;
 
+#if defined(__SVR4) && defined(__sun)
+	/*
+	 * Open the underlying kernel hardware driver that will
+	 * provide the mmap function for this context.
+	 */
+	context->mmap_fd = ibv_open_mmap_driver(context->device->dev_name);
+	if (context->mmap_fd < 0) {
+		fprintf(stderr, PFX "ibv_cmd_get_context: Mmap open failed\n");
+	}
+#endif
 	return 0;
 }
 
@@ -120,6 +207,7 @@
 	memset(device_attr->fw_ver, 0, sizeof device_attr->fw_ver);
 	*raw_fw_ver			       = resp.fw_ver;
 	device_attr->node_guid 		       = resp.node_guid;
+	device_attr->node_guid_external	       = resp.node_guid_external;
 	device_attr->sys_image_guid 	       = resp.sys_image_guid;
 	device_attr->max_mr_size 	       = resp.max_mr_size;
 	device_attr->page_size_cap 	       = resp.page_size_cap;
@@ -207,6 +295,8 @@
 {
 	IBV_INIT_CMD_RESP(cmd, cmd_size, ALLOC_PD, resp, resp_size);
 
+	cmd->user_handle     = (uintptr_t) pd;
+
 	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
 		return errno;
 
@@ -218,6 +308,47 @@
 	return 0;
 }
 
+int ibv_cmd_alloc_shpd(struct ibv_context *context, struct ibv_pd *pd,
+         uint64_t share_key, struct ibv_shpd *shpd,
+		     struct ibv_alloc_shpd *cmd, size_t cmd_size,
+		     struct ibv_alloc_shpd_resp *resp, size_t resp_size)
+{
+	IBV_INIT_CMD_RESP(cmd, cmd_size, ALLOC_SHPD, resp, resp_size);
+        cmd->pd_handle = pd->handle;
+	cmd->user_handle = (uintptr_t) pd;
+	cmd->share_key = share_key;
+
+	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
+		return errno;
+
+	VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
+
+	shpd->handle  = resp->shpd_handle;
+
+	return 0;
+}
+
+int ibv_cmd_share_pd(struct ibv_context *context, struct ibv_shpd *shpd,
+         uint64_t share_key, struct ibv_pd *pd,
+		     struct ibv_share_pd *cmd, size_t cmd_size,
+		     struct ibv_share_pd_resp *resp, size_t resp_size)
+{
+	IBV_INIT_CMD_RESP(cmd, cmd_size, SHARE_PD, resp, resp_size);
+	cmd->shpd_handle = shpd->handle;
+	cmd->share_key = share_key;
+	cmd->user_handle     = (uintptr_t) pd;
+
+	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
+		return errno;
+
+	VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
+
+	pd->handle  = resp->pd_handle;
+	pd->context = context;
+
+	return 0;
+}
+
 int ibv_cmd_dealloc_pd(struct ibv_pd *pd)
 {
 	struct ibv_dealloc_pd cmd;
@@ -224,6 +355,7 @@
 
 	IBV_INIT_CMD(&cmd, sizeof cmd, DEALLOC_PD);
 	cmd.pd_handle = pd->handle;
+	cmd.user_handle = (uintptr_t) pd;
 
 	if (write(pd->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
 		return errno;
@@ -244,6 +376,7 @@
 	cmd->length 	  = length;
 	cmd->hca_va 	  = hca_va;
 	cmd->pd_handle 	  = pd->handle;
+	cmd->user_handle  = (uintptr_t) mr;
 	cmd->access_flags = access;
 
 	if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
@@ -259,6 +392,35 @@
 	return 0;
 }
 
+int ibv_cmd_reg_mr_relaxed(struct ibv_pd *pd, void *addr, size_t length,
+		   uint64_t hca_va, int access,
+		   struct ibv_mr *mr, struct ibv_reg_mr *cmd,
+		   size_t cmd_size,
+		   struct ibv_reg_mr_resp *resp, size_t resp_size)
+{
+
+	IBV_INIT_CMD_RESP(cmd, cmd_size, REG_MR_RELAXED, resp, resp_size);
+
+	cmd->start 	  = (uintptr_t) addr;
+	cmd->length 	  = length;
+	cmd->hca_va 	  = hca_va;
+	cmd->pd_handle 	  = pd->handle;
+	cmd->user_handle  = (uintptr_t) mr;
+	cmd->access_flags = access;
+
+	if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
+		return errno;
+
+	VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
+
+	mr->handle  = resp->mr_handle;
+	mr->lkey    = resp->lkey;
+	mr->rkey    = resp->rkey;
+	mr->context = pd->context;
+
+	return 0;
+}
+
 int ibv_cmd_dereg_mr(struct ibv_mr *mr)
 {
 	struct ibv_dereg_mr cmd;
@@ -265,6 +427,7 @@
 
 	IBV_INIT_CMD(&cmd, sizeof cmd, DEREG_MR);
 	cmd.mr_handle = mr->handle;
+	cmd.user_handle  = (uintptr_t) mr;
 
 	if (write(mr->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
 		return errno;
@@ -272,6 +435,34 @@
 	return 0;
 }
 
+int ibv_cmd_dereg_mr_relaxed(struct ibv_mr *mr)
+{
+	struct ibv_dereg_mr cmd;
+
+	IBV_INIT_CMD(&cmd, sizeof cmd, DEREG_MR_RELAXED);
+	cmd.mr_handle = mr->handle;
+	cmd.user_handle  = (uintptr_t) mr;
+
+	if (write(mr->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+		return errno;
+
+	return 0;
+}
+
+int ibv_cmd_flush_relaxed_mr(struct ibv_pd *pd)
+{
+	struct ibv_flush_relaxed_mr cmd;
+
+	IBV_INIT_CMD(&cmd, sizeof cmd, FLUSH_RELAXED_MR);
+	cmd.pd_handle = pd->handle;
+	cmd.user_handle  = (uintptr_t) pd;
+
+	if (write(pd->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
+		return errno;
+
+	return 0;
+}
+
 static int ibv_cmd_create_cq_v2(struct ibv_context *context, int cqe,
 				struct ibv_cq *cq,
 				struct ibv_create_cq *new_cmd, size_t new_cmd_size,
@@ -315,7 +506,19 @@
 	cmd->user_handle   = (uintptr_t) cq;
 	cmd->cqe           = cqe;
 	cmd->comp_vector   = comp_vector;
+#if defined(__SVR4) && defined(__sun)
+	if (channel) {
+		struct stat	fstat_buf;
+
+		if (fstat(channel->fd, &fstat_buf))
+			return (errno);
+		else
+			cmd->comp_channel = minor(fstat_buf.st_rdev);
+	} else 
+		cmd->comp_channel = 0;
+#else
 	cmd->comp_channel  = channel ? channel->fd : -1;
+#endif
 	cmd->reserved      = 0;
 
 	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
@@ -346,6 +549,7 @@
 	IBV_INIT_CMD_RESP(&cmd, sizeof cmd, POLL_CQ, resp, rsize);
 	cmd.cq_handle = ibcq->handle;
 	cmd.ne        = ne;
+	cmd.user_handle  = (uintptr_t) ibcq;
 
 	if (write(ibcq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) {
 		ret = -1;
@@ -384,6 +588,7 @@
 	IBV_INIT_CMD(&cmd, sizeof cmd, REQ_NOTIFY_CQ);
 	cmd.cq_handle = ibcq->handle;
 	cmd.solicited = !!solicited_only;
+	cmd.user_handle  = (uintptr_t) ibcq;
 
 	if (write(ibcq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
 		return errno;
@@ -399,6 +604,7 @@
 	IBV_INIT_CMD_RESP(cmd, cmd_size, RESIZE_CQ, resp, resp_size);
 	cmd->cq_handle = cq->handle;
 	cmd->cqe       = cqe;
+	cmd->user_handle   = (uintptr_t) cq;
 
 	if (write(cq->context->cmd_fd, cmd, cmd_size) != cmd_size)
 		return errno;
@@ -434,6 +640,7 @@
 	IBV_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_CQ, &resp, sizeof resp);
 	cmd.cq_handle = cq->handle;
 	cmd.reserved  = 0;
+	cmd.user_handle  = (uintptr_t) cq;
 
 	if (write(cq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
 		return errno;
@@ -555,6 +762,7 @@
 	cmd->attr_mask	= srq_attr_mask;
 	cmd->max_wr	= srq_attr->max_wr;
 	cmd->srq_limit	= srq_attr->srq_limit;
+	cmd->user_handle   = (uintptr_t) srq;
 
 	if (write(srq->context->cmd_fd, cmd, cmd_size) != cmd_size)
 		return errno;
@@ -569,6 +777,7 @@
 
 	IBV_INIT_CMD_RESP(cmd, cmd_size, QUERY_SRQ, &resp, sizeof resp);
 	cmd->srq_handle = srq->handle;
+	cmd->user_handle   = (uintptr_t) srq;
 	cmd->reserved   = 0;
 
 	if (write(srq->context->cmd_fd, cmd, cmd_size) != cmd_size)
@@ -606,6 +815,7 @@
 
 	IBV_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_SRQ, &resp, sizeof resp);
 	cmd.srq_handle = srq->handle;
+	cmd.user_handle  = (uintptr_t) srq;
 	cmd.reserved   = 0;
 
 	if (write(srq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
@@ -637,7 +847,20 @@
 	cmd->max_send_sge    = attr->cap.max_send_sge;
 	cmd->max_recv_sge    = attr->cap.max_recv_sge;
 	cmd->max_inline_data = attr->cap.max_inline_data;
+
+#if defined(__SVR4) && defined(__sun)
+	if (attr->sq_sig_all & LIB_RDMACM_QP_BIT) {
+		cmd->sq_sig_all =
+		    (uint8_t)(attr->sq_sig_all & ~LIB_RDMACM_QP_BIT);
+		cmd->sq_sig_all |= 0x80;
+		attr->sq_sig_all &= ~LIB_RDMACM_QP_BIT;
+	} else {
+		cmd->sq_sig_all = (uint8_t)attr->sq_sig_all;
+	}
+#else
 	cmd->sq_sig_all	     = attr->sq_sig_all;
+#endif
+
 	cmd->qp_type 	     = attr->qp_type;
 	cmd->is_srq 	     = !!attr->srq;
 	cmd->srq_handle      = attr->qp_type == IBV_QPT_XRC ?
@@ -691,6 +914,7 @@
 	IBV_INIT_CMD_RESP(cmd, cmd_size, QUERY_QP, &resp, sizeof resp);
 	cmd->qp_handle = qp->handle;
 	cmd->attr_mask = attr_mask;
+	cmd->user_handle   = (uintptr_t) qp;
 
 	if (write(qp->context->cmd_fd, cmd, cmd_size) != cmd_size)
 		return errno;
@@ -772,6 +996,7 @@
 	IBV_INIT_CMD(cmd, cmd_size, MODIFY_QP);
 
 	cmd->qp_handle 		 = qp->handle;
+	cmd->user_handle   	 = (uintptr_t) qp;
 	cmd->attr_mask 		 = attr_mask;
 	cmd->qkey 		 = attr->qkey;
 	cmd->rq_psn 		 = attr->rq_psn;
@@ -1292,6 +1517,7 @@
 	IBV_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_QP, &resp, sizeof resp);
 	cmd.qp_handle = qp->handle;
 	cmd.reserved  = 0;
+	cmd.user_handle  = (uintptr_t) qp;
 
 	if (write(qp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
 		return errno;
@@ -1313,6 +1539,7 @@
 	IBV_INIT_CMD(&cmd, sizeof cmd, ATTACH_MCAST);
 	memcpy(cmd.gid, gid->raw, sizeof cmd.gid);
 	cmd.qp_handle = qp->handle;
+	cmd.user_handle  = (uintptr_t) qp;
 	cmd.mlid      = lid;
 	cmd.reserved  = 0;
 
@@ -1329,6 +1556,7 @@
 	IBV_INIT_CMD(&cmd, sizeof cmd, DETACH_MCAST);
 	memcpy(cmd.gid, gid->raw, sizeof cmd.gid);
 	cmd.qp_handle = qp->handle;
+	cmd.user_handle  = (uintptr_t) qp;
 	cmd.mlid      = lid;
 	cmd.reserved  = 0;
 
@@ -1406,4 +1634,3 @@
 		return errno;
 	return 0;
 }
-
diff -r -u /tmp/846623/libibverbs-1.1.4/src/init.c libibverbs-1.1.4/src/init.c
--- /tmp/846623/libibverbs-1.1.4/src/init.c	Sun Nov  1 06:47:19 2009
+++ libibverbs-1.1.4/src/init.c	Fri Feb 11 04:02:32 2011
@@ -77,8 +77,13 @@
 static struct ibv_driver_name *driver_name_list;
 static struct ibv_driver *head_driver, *tail_driver;
 
+static uint blueflame_enabled = 0;
+
 static int find_sysfs_devs(void)
 {
+#if defined(__SVR4) && defined(__sun)
+	char device_path[IBV_SYSFS_PATH_MAX];
+#endif
 	char class_path[IBV_SYSFS_PATH_MAX];
 	DIR *class_dir;
 	struct dirent *dent;
@@ -86,19 +91,35 @@
 	char value[8];
 	int ret = 0;
 
+#if defined(__SVR4) && defined(__sun)
+	snprintf(device_path, sizeof device_path, "/dev/infiniband/ofs");
+#endif
 	snprintf(class_path, sizeof class_path, "%s/class/infiniband_verbs",
 		 ibv_get_sysfs_path());
 
+#if defined(__SVR4) && defined(__sun)
+	class_dir = opendir(device_path);
+#else
 	class_dir = opendir(class_path);
+#endif
 	if (!class_dir)
 		return ENOSYS;
 
 	while ((dent = readdir(class_dir))) {
+#if defined(__SVR4) && defined(__sun)
+		int adapter_num;
+#else
 		struct stat buf;
+#endif
 
 		if (dent->d_name[0] == '.')
 			continue;
 
+#if defined(__SVR4) && defined(__sun)
+		if (sscanf(dent->d_name, "uverbs%d",
+		    &adapter_num) != 1)
+			continue;
+#endif
 		if (!sysfs_dev)
 			sysfs_dev = malloc(sizeof *sysfs_dev);
 		if (!sysfs_dev) {
@@ -109,6 +130,7 @@
 		snprintf(sysfs_dev->sysfs_path, sizeof sysfs_dev->sysfs_path,
 			 "%s/%s", class_path, dent->d_name);
 
+#if !(defined(__SVR4) && defined(__sun))
 		if (stat(sysfs_dev->sysfs_path, &buf)) {
 			fprintf(stderr, PFX "Warning: couldn't stat '%s'.\n",
 				sysfs_dev->sysfs_path);
@@ -117,6 +139,7 @@
 
 		if (!S_ISDIR(buf.st_mode))
 			continue;
+#endif
 
 		snprintf(sysfs_dev->sysfs_name, sizeof sysfs_dev->sysfs_name,
 			"%s", dent->d_name);
@@ -280,6 +303,13 @@
 
 			driver_name->next = driver_name_list;
 			driver_name_list  = driver_name;
+		} else if (strcmp(field, "blueflame") == 0) {
+			config += strspn(config, "\t ");
+			field = strsep(&config, "\n\t ");
+			if (strcmp(field, "enable") == 0)
+				blueflame_enabled = 1;
+			if (strcmp(field, "disable") == 0)
+				blueflame_enabled = 0;
 		} else
 			fprintf(stderr, PFX "Warning: ignoring bad config directive "
 				"'%s' in file '%s'.\n", field, path);
@@ -367,6 +397,7 @@
 	strcpy(dev->dev_path,   sysfs_dev->sysfs_path);
 	strcpy(dev->name,       sysfs_dev->ibdev_name);
 	strcpy(dev->ibdev_path, sysfs_dev->ibdev_path);
+	dev->blueflame_enabled = blueflame_enabled;
 
 	return dev;
 }
@@ -409,6 +440,7 @@
 
 static void check_memlock_limit(void)
 {
+#if !(defined(__SVR4) && defined(__sun))
 	struct rlimit rlim;
 
 	if (!geteuid())
@@ -423,6 +455,7 @@
 		fprintf(stderr, PFX "Warning: RLIMIT_MEMLOCK is %lu bytes.\n"
 			"    This will severely limit memory registrations.\n",
 			rlim.rlim_cur);
+#endif
 }
 
 static void add_device(struct ibv_device *dev,
diff -r -u /tmp/846623/libibverbs-1.1.4/src/enum_strs.c libibverbs-1.1.4/src/enum_strs.c
--- /tmp/846623/libibverbs-1.1.4/src/enum_strs.c	Wed Sep 16 04:27:22 2009
+++ libibverbs-1.1.4/src/enum_strs.c	Tue Mar 20 16:27:45 2012
@@ -85,9 +85,14 @@
 		[IBV_EVENT_SRQ_LIMIT_REACHED]	= "SRQ limit reached",
 		[IBV_EVENT_QP_LAST_WQE_REACHED]	= "last WQE reached",
 		[IBV_EVENT_CLIENT_REREGISTER]	= "client reregistration",
+		[IBV_EVENT_GID_CHANGE]		= "GID change",
+		[IBV_EVENT_MCG_CREATED]		= "MCG created",
+		[IBV_EVENT_MCG_DELETED]		= "MCG deleted",
+		[IBV_EVENT_GID_AVAIL]		= "GID available",
+		[IBV_EVENT_GID_UNAVAIL]		= "GID unavailable",
 	};
 
-	if (event < IBV_EVENT_CQ_ERR || event > IBV_EVENT_CLIENT_REREGISTER)
+	if (event < IBV_EVENT_CQ_ERR || event > IBV_EVENT_GID_UNAVAIL)
 		return "unknown";
 
 	return event_type_str[event];
diff -r -u /tmp/846623/libibverbs-1.1.4/src/sysfs.c libibverbs-1.1.4/src/sysfs.c
--- /tmp/846623/libibverbs-1.1.4/src/sysfs.c	Wed Sep 16 04:27:22 2009
+++ libibverbs-1.1.4/src/sysfs.c	Fri Feb 11 04:02:33 2011
@@ -44,6 +44,10 @@
 
 #include "ibverbs.h"
 
+#if defined(__SVR4) && defined(__sun)
+int sol_read_sysfs_file(char *path, char *buf, size_t size);
+#endif
+
 static char *sysfs_path;
 
 const char *ibv_get_sysfs_path(void)
@@ -79,12 +83,18 @@
 			char *buf, size_t size)
 {
 	char *path;
+#if !(defined(__SVR4) && defined(__sun))
 	int fd;
+#endif
 	int len;
 
 	if (asprintf(&path, "%s/%s", dir, file) < 0)
 		return -1;
 
+#if defined(__SVR4) && defined(__sun)
+	len = sol_read_sysfs_file(path, buf, size);
+	free(path);
+#else
 	fd = open(path, O_RDONLY);
 	if (fd < 0) {
 		free(path);
@@ -98,6 +108,7 @@
 
 	if (len > 0 && buf[len - 1] == '\n')
 		buf[--len] = '\0';
+#endif
 
 	return len;
 }
diff -r -u /tmp/846623/libibverbs-1.1.4/configure libibverbs-1.1.4/configure
--- /tmp/846623/libibverbs-1.1.4/configure	Thu Feb  3 01:53:23 2011
+++ libibverbs-1.1.4/configure	Fri Feb 11 04:02:14 2011
@@ -3173,6 +3173,7 @@
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
 $as_echo_n "checking whether the C compiler works... " >&6; }
 ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+ac_link_default=`$as_echo "$ac_link" | sed 's/ \$LIBS//'`
 
 # The possible output files:
 ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
@@ -3258,6 +3259,7 @@
 ac_clean_files=$ac_clean_files_save
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
 $as_echo_n "checking for suffix of executables... " >&6; }
+ac_link_nolibs=`$as_echo "$ac_link" | sed 's/ \$LIBS//'`
 if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -3265,7 +3267,7 @@
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
 $as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
+  (eval "$ac_link_nolibs") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then :
@@ -3321,7 +3323,7 @@
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
 $as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
+  (eval "$ac_link_nolibs") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
@@ -3509,13 +3511,13 @@
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
+    CFLAGS="-g -O3"
   else
     CFLAGS="-g"
   fi
 else
   if test "$GCC" = yes; then
-    CFLAGS="-O2"
+    CFLAGS="-O3"
   else
     CFLAGS=
   fi
@@ -8721,6 +8723,7 @@
 	;;
       esac
       link_all_deplibs=yes
+	 hardcode_libdir_flag_spec=
       ;;
 
     sunos4*)
@@ -10945,13 +10948,13 @@
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
+    CFLAGS="-g -O3"
   else
     CFLAGS="-g"
   fi
 else
   if test "$GCC" = yes; then
-    CFLAGS="-O2"
+    CFLAGS="-O3"
   else
     CFLAGS=
   fi
@@ -11198,7 +11201,7 @@
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl  $LIBS"
+LIBS="-ldl"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -11245,7 +11248,7 @@
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpthread  $LIBS"
+LIBS="-lpthread"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
diff -r -u /tmp/846623/libibverbs-1.1.4/include/infiniband/sa-kern-abi.h libibverbs-1.1.4/include/infiniband/sa-kern-abi.h
--- /tmp/846623/libibverbs-1.1.4/include/infiniband/sa-kern-abi.h	Wed Sep 16 04:27:22 2009
+++ libibverbs-1.1.4/include/infiniband/sa-kern-abi.h	Fri Feb 11 04:02:21 2011
@@ -33,7 +33,11 @@
 #ifndef INFINIBAND_SA_KERN_ABI_H
 #define INFINIBAND_SA_KERN_ABI_H
 
+#if !(defined(__SVR4) && defined(__sun))
 #include <linux/types.h>
+#else
+#include <infiniband/ofa_solaris.h>
+#endif
 
 /*
  * Obsolete, deprecated names.  Will be removed in libibverbs 1.1.
diff -r -u /tmp/846623/libibverbs-1.1.4/include/infiniband/kern-abi.h libibverbs-1.1.4/include/infiniband/kern-abi.h
--- /tmp/846623/libibverbs-1.1.4/include/infiniband/kern-abi.h	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/include/infiniband/kern-abi.h	Fri Feb 11 04:02:20 2011
@@ -35,7 +35,11 @@
 #ifndef KERN_ABI_H
 #define KERN_ABI_H
 
+#if !(defined(__SVR4) && defined(__sun))
 #include <linux/types.h>
+#else
+#include <infiniband/ofa_solaris.h>
+#endif
 
 /*
  * This file must be kept in sync with the kernel's version of
@@ -94,6 +98,14 @@
 	IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP,
 	IB_USER_VERBS_CMD_REG_XRC_RCV_QP,
 	IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP,
+	IB_USER_VERBS_CMD_REG_MR_RELAXED,
+	IB_USER_VERBS_CMD_DEREG_MR_RELAXED,
+	IB_USER_VERBS_CMD_FLUSH_RELAXED_MR,
+	IB_USER_VERBS_CMD_ALLOC_SHPD,
+	IB_USER_VERBS_CMD_SHARE_PD,
+	IB_USER_VERBS_CMD_REG_SM_EVENT,
+	IB_USER_VERBS_CMD_UNREG_SM_EVENT,
+	IB_USER_VERBS_CMD_GID_REACHABLE
 };
 
 /*
@@ -111,6 +123,8 @@
 	__u64 element;
 	__u32 event_type;
 	__u32 reserved;
+	__u64 subnet_prefix;
+	__u64 interface_id;
 };
 
 struct ibv_comp_event {
@@ -160,6 +174,7 @@
 struct ibv_query_device_resp {
 	__u64 fw_ver;
 	__u64 node_guid;
+	__u64 node_guid_external;
 	__u64 sys_image_guid;
 	__u64 max_mr_size;
 	__u64 page_size_cap;
@@ -235,23 +250,103 @@
 	__u8  reserved[2];
 };
 
+struct ibv_reg_sm_event {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+	__u32 events;
+	__u32 data_num;
+	__u64 driver_data[0];
+};
+
+struct ibv_unreg_sm_event {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+	__u32 events;
+	__u32 data_num;
+	__u64 driver_data[0];
+};
+
+struct ibv_gid_reachable {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+	__u32 timeout;
+	__u8  port_num;
+	__u8  reserved[3];
+	__u8  gid[16];
+};
+
 struct ibv_alloc_pd {
 	__u32 command;
 	__u16 in_words;
 	__u16 out_words;
 	__u64 response;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
+#if defined(__SVR4) && defined(__sun)
+/*
+ * PD responses may pass opaque data to userspace drivers, we choose a value
+ * larger than what any HCA requires.
+ */
+#define SOL_UVERBS_PD_DATA_OUT_SIZE          24
+typedef __u64 ofuv_pd_drv_data_out_t[SOL_UVERBS_PD_DATA_OUT_SIZE];
+
 struct ibv_alloc_pd_resp {
+        __u32 pd_handle;
+        __u32 reserved;
+        ofuv_pd_drv_data_out_t drv_out;
+};
+#else
+struct ibv_alloc_pd_resp {
 	__u32 pd_handle;
 };
+#endif
 
+struct ibv_alloc_shpd {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+	__u64 response;
+	__u32 pd_handle;
+	__u32 reserved;
+	__u64 share_key;
+	__u64 user_handle;
+	__u64 driver_data[0];
+};
+
+struct ibv_alloc_shpd_resp {
+	__u32 shpd_handle;
+};
+
+struct ibv_share_pd {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+	__u64 response;
+	__u32 shpd_handle;
+	__u32 reserved;
+	__u64 share_key;
+	__u64 user_handle;
+	__u64 driver_data[0];
+};
+
+struct ibv_share_pd_resp {
+	__u32 pd_handle;
+        __u32 reserved;
+        ofuv_pd_drv_data_out_t drv_out;
+};
+
 struct ibv_dealloc_pd {
 	__u32 command;
 	__u16 in_words;
 	__u16 out_words;
 	__u32 pd_handle;
+	__u32 reserved;
+	__u64 user_handle;
 };
 
 struct ibv_reg_mr {
@@ -264,6 +359,7 @@
 	__u64 hca_va;
 	__u32 pd_handle;
 	__u32 access_flags;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -278,8 +374,19 @@
 	__u16 in_words;
 	__u16 out_words;
 	__u32 mr_handle;
+	__u32 reserved;
+	__u64 user_handle;
 };
 
+struct ibv_flush_relaxed_mr {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+	__u32 pd_handle;
+	__u32 reserved;
+	__u64 user_handle;
+};
+
 struct ibv_create_comp_channel {
 	__u32 command;
 	__u16 in_words;
@@ -304,10 +411,25 @@
 	__u64 driver_data[0];
 };
 
+#if defined(__SVR4) && defined(__sun)
+/*
+ * CQ responses pass opaque data to userspace drivers, we choose a value
+ * larger than what any HCA requires.
+ */
+#define SOL_UVERBS_CQ_DATA_OUT_SIZE          24
+typedef __u64 ofuv_cq_drv_data_out_t[SOL_UVERBS_CQ_DATA_OUT_SIZE];
+
 struct ibv_create_cq_resp {
 	__u32 cq_handle;
 	__u32 cqe;
+	ofuv_cq_drv_data_out_t   drv_out;
 };
+#else
+struct ibv_create_cq_resp {
+	__u32 cq_handle;
+	__u32 cqe;
+};
+#endif
 
 struct ibv_kern_wc {
 	__u64  wr_id;
@@ -334,6 +456,7 @@
 	__u64 response;
 	__u32 cq_handle;
 	__u32 ne;
+	__u64 user_handle;
 };
 
 struct ibv_poll_cq_resp {
@@ -348,6 +471,7 @@
 	__u16 out_words;
 	__u32 cq_handle;
 	__u32 solicited;
+	__u64 user_handle;
 };
 
 struct ibv_resize_cq {
@@ -357,6 +481,7 @@
 	__u64 response;
 	__u32 cq_handle;
 	__u32 cqe;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -363,7 +488,11 @@
 struct ibv_resize_cq_resp {
 	__u32 cqe;
 	__u32 reserved;
+#if defined(__SVR4) && defined(__sun)
+        ofuv_cq_drv_data_out_t   drv_out;
+#else
 	__u64 driver_data[0];
+#endif
 };
 
 struct ibv_destroy_cq {
@@ -373,6 +502,7 @@
 	__u64 response;
 	__u32 cq_handle;
 	__u32 reserved;
+	__u64 user_handle;
 };
 
 struct ibv_destroy_cq_resp {
@@ -460,6 +590,14 @@
 	__u64 driver_data[0];
 };
 
+#if defined(__SVR4) && defined(__sun)
+/*
+ * QP responses pass opaque data to userspace drivers, we choose a value
+ * larger than what any HCA requires.
+ */
+#define SOL_UVERBS_QP_DATA_OUT_SIZE          24
+typedef __u64 ofuv_qp_drv_data_out_t[SOL_UVERBS_QP_DATA_OUT_SIZE];
+
 struct ibv_create_qp_resp {
 	__u32 qp_handle;
 	__u32 qpn;
@@ -469,7 +607,20 @@
 	__u32 max_recv_sge;
 	__u32 max_inline_data;
 	__u32 reserved;
+	ofuv_qp_drv_data_out_t drv_out;
 };
+#else
+struct ibv_create_qp_resp {
+	__u32 qp_handle;
+	__u32 qpn;
+	__u32 max_send_wr;
+	__u32 max_recv_wr;
+	__u32 max_send_sge;
+	__u32 max_recv_sge;
+	__u32 max_inline_data;
+	__u32 reserved;
+};
+#endif
 
 struct ibv_qp_dest {
 	__u8  dgid[16];
@@ -493,6 +644,7 @@
 	__u64 response;
 	__u32 qp_handle;
 	__u32 attr_mask;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -560,6 +712,7 @@
 	__u8  alt_port_num;
 	__u8  alt_timeout;
 	__u8  reserved[2];
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -570,6 +723,7 @@
 	__u64 response;
 	__u32 qp_handle;
 	__u32 reserved;
+	__u64 user_handle;
 };
 
 struct ibv_destroy_qp_resp {
@@ -775,6 +929,7 @@
 	__u32 qp_handle;
 	__u16 mlid;
 	__u16 reserved;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -786,6 +941,7 @@
 	__u32 qp_handle;
 	__u16 mlid;
 	__u16 reserved;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -817,12 +973,29 @@
 	__u64 driver_data[0];
 };
 
+#if defined(__SVR4) && defined(__sun)
+/*
+ * QP responses pass opaque data to userspace drivers, we choose a value
+ * larger than what any HCA requires.
+ */
+#define SOL_UVERBS_SRQ_DATA_OUT_SIZE          24
+typedef __u64 ofuv_srq_drv_data_out_t[SOL_UVERBS_SRQ_DATA_OUT_SIZE];
+
 struct ibv_create_srq_resp {
 	__u32 srq_handle;
 	__u32 max_wr;
 	__u32 max_sge;
 	__u32 reserved;
+	ofuv_srq_drv_data_out_t drv_out;
 };
+#else
+struct ibv_create_srq_resp {
+	__u32 srq_handle;
+	__u32 max_wr;
+	__u32 max_sge;
+	__u32 reserved;
+};
+#endif
 
 struct ibv_modify_srq {
 	__u32 command;
@@ -832,6 +1005,7 @@
 	__u32 attr_mask;
 	__u32 max_wr;
 	__u32 srq_limit;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -842,6 +1016,7 @@
 	__u64 response;
 	__u32 srq_handle;
 	__u32 reserved;
+	__u64 user_handle;
 	__u64 driver_data[0];
 };
 
@@ -859,6 +1034,7 @@
 	__u64 response;
 	__u32 srq_handle;
 	__u32 reserved;
+	__u64 user_handle;
 };
 
 struct ibv_destroy_srq_resp {
@@ -946,6 +1122,14 @@
 	IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP_V2 = -1,
 	IB_USER_VERBS_CMD_REG_XRC_RCV_QP_V2 = -1,
 	IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP_V2 = -1,
+	IB_USER_VERBS_CMD_REG_MR_RELAXED_V2 = -1,
+	IB_USER_VERBS_CMD_DEREG_MR_RELAXED_V2 = -1,
+	IB_USER_VERBS_CMD_FLUSH_RELAXED_MR_V2 = -1,
+  	IB_USER_VERBS_CMD_ALLOC_SHPD_V2 = -1,
+  	IB_USER_VERBS_CMD_SHARE_PD_V2 = -1,
+	IB_USER_VERBS_CMD_REG_SM_EVENT_V2 = -1,
+	IB_USER_VERBS_CMD_UNREG_SM_EVENT_V2 = -1,
+	IB_USER_VERBS_CMD_GID_REACHABLE_V2 = -1,
 };
 
 struct ibv_destroy_cq_v1 {
diff -r -u /tmp/846623/libibverbs-1.1.4/include/infiniband/driver.h libibverbs-1.1.4/include/infiniband/driver.h
--- /tmp/846623/libibverbs-1.1.4/include/infiniband/driver.h	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/include/infiniband/driver.h	Fri Feb 11 04:02:20 2011
@@ -74,6 +74,14 @@
 int ibv_cmd_alloc_pd(struct ibv_context *context, struct ibv_pd *pd,
 		     struct ibv_alloc_pd *cmd, size_t cmd_size,
 		     struct ibv_alloc_pd_resp *resp, size_t resp_size);
+int ibv_cmd_alloc_shpd(struct ibv_context *context, struct ibv_pd *pd,
+		     uint64_t share_key, struct ibv_shpd *shpd,
+		     struct ibv_alloc_shpd *cmd, size_t cmd_size,
+		     struct ibv_alloc_shpd_resp *resp, size_t resp_size);
+int ibv_cmd_share_pd(struct ibv_context *context, struct ibv_shpd *shpd,
+		     uint64_t share_key, struct ibv_pd *pd,
+		     struct ibv_share_pd *cmd, size_t cmd_size,
+		     struct ibv_share_pd_resp *resp, size_t resp_size);
 int ibv_cmd_dealloc_pd(struct ibv_pd *pd);
 #define IBV_CMD_REG_MR_HAS_RESP_PARAMS
 int ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length,
@@ -81,7 +89,15 @@
 		   struct ibv_mr *mr, struct ibv_reg_mr *cmd,
 		   size_t cmd_size,
 		   struct ibv_reg_mr_resp *resp, size_t resp_size);
+#define IBV_CMD_REG_MR_RELAXED_HAS_RESP_PARAMS
+int ibv_cmd_reg_mr_relaxed(struct ibv_pd *pd, void *addr, size_t length,
+		   uint64_t hca_va, int access,
+		   struct ibv_mr *mr, struct ibv_reg_mr *cmd,
+		   size_t cmd_size,
+		   struct ibv_reg_mr_resp *resp, size_t resp_size);
 int ibv_cmd_dereg_mr(struct ibv_mr *mr);
+int ibv_cmd_dereg_mr_relaxed(struct ibv_mr *mr);
+int ibv_cmd_flush_relaxed_mr(struct ibv_pd *pd);
 int ibv_cmd_create_cq(struct ibv_context *context, int cqe,
 		      struct ibv_comp_channel *channel,
 		      int comp_vector, struct ibv_cq *cq,
@@ -164,8 +180,8 @@
 int ibv_read_sysfs_file(const char *dir, const char *file,
 			char *buf, size_t size);
 
-int ibv_resolve_eth_gid(const struct ibv_pd *pd, uint8_t port_num,
-			union ibv_gid *dgid, uint8_t sgid_index,
+int ibv_resolve_eth_gid(struct ibv_pd *pd, uint8_t port_num,
+			const union ibv_gid *dgid, uint8_t sgid_index,
 			uint8_t mac[], uint16_t *vlan, uint8_t *tagged,
 			uint8_t *is_mcast);
 
diff -r -u /tmp/846623/libibverbs-1.1.4/include/infiniband/verbs.h libibverbs-1.1.4/include/infiniband/verbs.h
--- /tmp/846623/libibverbs-1.1.4/include/infiniband/verbs.h	Thu Feb  3 01:53:17 2011
+++ libibverbs-1.1.4/include/infiniband/verbs.h	Fri Feb 11 04:02:21 2011
@@ -38,6 +38,9 @@
 
 #include <stdint.h>
 #include <pthread.h>
+#if defined(__SVR4) && defined(__sun)
+#include <infiniband/ofa_solaris.h>
+#endif
 
 #ifdef __cplusplus
 #  define BEGIN_C_DECLS extern "C" {
@@ -105,6 +108,7 @@
 struct ibv_device_attr {
 	char			fw_ver[64];
 	uint64_t		node_guid;
+	uint64_t		node_guid_external;
 	uint64_t		sys_image_guid;
 	uint64_t		max_mr_size;
 	uint64_t		page_size_cap;
@@ -212,6 +216,10 @@
 	IBV_EVENT_QP_LAST_WQE_REACHED,
 	IBV_EVENT_CLIENT_REREGISTER,
 	IBV_EVENT_GID_CHANGE,
+	IBV_EVENT_MCG_CREATED,
+	IBV_EVENT_MCG_DELETED,
+	IBV_EVENT_GID_AVAIL,
+	IBV_EVENT_GID_UNAVAIL,
 };
 
 enum ibv_event_flags {
@@ -225,10 +233,20 @@
 		struct ibv_srq *srq;
 		int		port_num;
 		uint32_t	xrc_qp_num;
+		union ibv_gid	gid;
 	} element;
 	enum ibv_event_type	event_type;
 };
 
+typedef enum ibv_sm_event_type_e {
+	IBV_SM_EVENT_MGID	= 1,
+	IBV_SM_EVENT_MGID_ALL	= 1 << 2,
+	IBV_SM_EVENT_UGID	= 1 << 3,
+	IBV_SM_EVENT_UGID_ALL	= 1 << 4,
+        IBV_SM_EVENT_ALL	= 1 << 5
+
+} ibv_sm_event_type_t;
+
 enum ibv_wc_status {
 	IBV_WC_SUCCESS,
 	IBV_WC_LOC_LEN_ERR,
@@ -297,7 +315,8 @@
 	IBV_ACCESS_REMOTE_WRITE		= (1<<1),
 	IBV_ACCESS_REMOTE_READ		= (1<<2),
 	IBV_ACCESS_REMOTE_ATOMIC	= (1<<3),
-	IBV_ACCESS_MW_BIND		= (1<<4)
+	IBV_ACCESS_MW_BIND		= (1<<4),
+	IBV_ACCESS_SO			= (1<<5)	/* Strong Order */
 };
 
 struct ibv_pd {
@@ -305,6 +324,10 @@
 	uint32_t		handle;
 };
 
+struct ibv_shpd {
+	uint32_t		handle;
+};
+
 enum ibv_rereg_mr_flags {
 	IBV_REREG_MR_CHANGE_TRANSLATION	= (1 << 0),
 	IBV_REREG_MR_CHANGE_PD		= (1 << 1),
@@ -425,6 +448,14 @@
 	uint32_t		max_inline_data;
 };
 
+#if defined(__SVR4) && defined(__sun)
+/*
+ * The 31st bit of sq_sig_all is set for QPs allocated
+ * using librdmacm. Consumers use sq_sig_all 0 /1.
+ */
+#define LIB_RDMACM_QP_BIT	0x8000
+#endif
+
 struct ibv_qp_init_attr {
 	void		       *qp_context;
 	struct ibv_cq	       *send_cq;
@@ -659,6 +690,7 @@
 	char			dev_path[IBV_SYSFS_PATH_MAX];
 	/* Path to infiniband class device in sysfs */
 	char			ibdev_path[IBV_SYSFS_PATH_MAX];
+	uint                    blueflame_enabled;
 };
 
 struct ibv_more_ops {
@@ -743,6 +775,12 @@
 	int			(*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid,
 						uint16_t lid);
 	void			(*async_event)(struct ibv_async_event *event);
+	struct ibv_mr *		(*reg_mr_relaxed)(struct ibv_pd *pd, void *addr, size_t length,
+					  int access);
+	int			(*dereg_mr_relaxed)(struct ibv_mr *mr);
+	int			(*flush_relaxed_mr)(struct ibv_pd *pd);
+	struct ibv_shpd *	(*alloc_shpd)(struct ibv_pd *pd, uint64_t share_key, struct ibv_shpd *shpd);
+	struct ibv_pd *		(*share_pd)(struct ibv_context *context, struct ibv_shpd *shpd, uint64_t share_key);
 };
 
 struct ibv_context {
@@ -749,6 +787,13 @@
 	struct ibv_device      *device;
 	struct ibv_context_ops	ops;
 	int			cmd_fd;
+#if defined(__SVR4) && defined(__sun)
+	/*
+	 * Solaris user libraries use this FD for mmap operations. It is an
+	 * open to the underlying kernel hardware specific driver.
+	 */
+	int			mmap_fd;
+#endif
 	int			async_fd;
 	int			num_comp_vectors;
 	pthread_mutex_t		mutex;
@@ -797,6 +842,11 @@
 uint64_t ibv_get_device_guid(struct ibv_device *device);
 
 /**
+ * ibv_get_device_guid_external - Return device's node external GUID
+ */
+uint64_t ibv_get_device_guid_external(struct ibv_device *device);
+
+/**
  * ibv_open_device - Initialize device for use
  */
 struct ibv_context *ibv_open_device(struct ibv_device *device);
@@ -853,11 +903,44 @@
 		   int index, uint16_t *pkey);
 
 /**
+ * ibv_register_sm_events - Register subnet event for GID change
+ */
+int ibv_register_sm_events(struct ibv_context *context,
+    ibv_sm_event_type_t event, uint_t gid_num, union ibv_gid *gids);
+
+/**
+ * ibv_unregister_sm_events - Unregister subnet event for GID change
+ */
+int ibv_unregister_sm_events(struct ibv_context *context,
+    ibv_sm_event_type_t event, uint_t gid_num, union ibv_gid *gids);
+
+/**
+ * ibv_gid_reachable - To contact subnet agent for GID status; reachable or
+ * not reachable
+ */
+int ibv_gid_reachable(struct ibv_context *context,
+    uint port, union ibv_gid *gid_p, int timeout);
+
+/**
  * ibv_alloc_pd - Allocate a protection domain
  */
 struct ibv_pd *ibv_alloc_pd(struct ibv_context *context);
 
 /**
+ * ibv_alloc_shpd - Mark given protection domain as shareable & return shpd structure
+ *                  that identify it.
+ *                  the storage for shpd structure needs to be provided by client.
+ */
+struct ibv_shpd *ibv_alloc_shpd(struct ibv_pd *pd, uint64_t share_key, struct ibv_shpd *shpd);
+
+/**
+ * ibv_share_pd - share the protection domain identified by given shpd struct & return a
+ *                process linked ibv_pd struct.
+ *                the share_key given should match with the share_key specifed in alloc_shpd().
+ */
+struct ibv_pd *ibv_share_pd(struct ibv_context *context, struct ibv_shpd *shpd, uint64_t share_key);
+
+/**
  * ibv_dealloc_pd - Free a protection domain
  */
 int ibv_dealloc_pd(struct ibv_pd *pd);
@@ -869,11 +952,27 @@
 			  size_t length, int access);
 
 /**
+ * ibv_reg_mr_relaxed - Register a memory region using FMR
+ */
+struct ibv_mr *ibv_reg_mr_relaxed(struct ibv_pd *pd, void *addr,
+			  size_t length, int access);
+
+/**
  * ibv_dereg_mr - Deregister a memory region
  */
 int ibv_dereg_mr(struct ibv_mr *mr);
 
 /**
+ * ibv_dereg_mr_relaxed - Deregister a memory region registered using FMR
+ */
+int ibv_dereg_mr_relaxed(struct ibv_mr *mr);
+
+/**
+ * ibv_flush_relaxed_mr - Flush all free mr's in the protection domain
+ */
+int ibv_flush_relaxed_mr(struct ibv_pd *pd);
+
+/**
  * ibv_create_comp_channel - Create a completion event channel
  */
 struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context *context);
diff -r -u /tmp/846623/libibverbs-1.1.4/include/infiniband/arch.h libibverbs-1.1.4/include/infiniband/arch.h
--- /tmp/846623/libibverbs-1.1.4/include/infiniband/arch.h	Wed Sep 16 04:27:22 2009
+++ libibverbs-1.1.4/include/infiniband/arch.h	Fri Feb 11 04:02:20 2011
@@ -34,6 +34,7 @@
 #define INFINIBAND_ARCH_H
 
 #include <stdint.h>
+#if !(defined(__SVR4) && defined(__sun))
 #include <endian.h>
 #include <byteswap.h>
 
@@ -46,6 +47,9 @@
 #else
 #error __BYTE_ORDER is neither __LITTLE_ENDIAN nor __BIG_ENDIAN
 #endif
+#else
+#include <infiniband/ofa_solaris.h>
+#endif
 
 /*
  * Architecture-specific defines.  Currently, an architecture is
diff -r -u /tmp/846623/libibverbs-1.1.4/Makefile.in libibverbs-1.1.4/Makefile.in
--- /tmp/846623/libibverbs-1.1.4/Makefile.in	Thu Feb  3 01:53:23 2011
+++ libibverbs-1.1.4/Makefile.in	Fri Feb 11 05:27:45 2011
@@ -90,7 +90,8 @@
 	src_libibverbs_la-compat-1_0.lo src_libibverbs_la-device.lo \
 	src_libibverbs_la-init.lo src_libibverbs_la-marshall.lo \
 	src_libibverbs_la-memory.lo src_libibverbs_la-sysfs.lo \
-	src_libibverbs_la-verbs.lo src_libibverbs_la-enum_strs.lo
+	src_libibverbs_la-verbs.lo src_libibverbs_la-enum_strs.lo \
+	src_libibverbs_la-solaris.lo
 src_libibverbs_la_OBJECTS = $(am_src_libibverbs_la_OBJECTS)
 AM_V_lt = $(am__v_lt_$(V))
 am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -313,11 +314,11 @@
 INCLUDES = -I$(srcdir)/include
 lib_LTLIBRARIES = src/libibverbs.la
 AM_CFLAGS = -g -Wall -D_GNU_SOURCE
-src_libibverbs_la_CFLAGS = $(AM_CFLAGS) -DIBV_CONFIG_DIR=\"$(sysconfdir)/libibverbs.d\"
+src_libibverbs_la_CFLAGS = $(AM_CFLAGS) -DIBV_CONFIG_DIR=\"$(datadir)/libibverbs.d\"
 libibverbs_version_script = @LIBIBVERBS_VERSION_SCRIPT@
 src_libibverbs_la_SOURCES = src/cmd.c src/compat-1_0.c src/device.c src/init.c \
 			    src/marshall.c src/memory.c src/sysfs.c src/verbs.c \
-			    src/enum_strs.c
+			    src/enum_strs.c src/solaris_compatability src/verbs.c
 
 src_libibverbs_la_LDFLAGS = -version-info 1 -export-dynamic \
     $(libibverbs_version_script)
@@ -340,6 +341,7 @@
 libibverbsincludedir = $(includedir)/infiniband
 libibverbsinclude_HEADERS = include/infiniband/arch.h include/infiniband/driver.h \
     include/infiniband/kern-abi.h include/infiniband/opcode.h include/infiniband/verbs.h \
+	include/infiniband/ofa_solaris.h \
     include/infiniband/sa-kern-abi.h include/infiniband/sa.h include/infiniband/marshall.h
 
 man_MANS = man/ibv_asyncwatch.1 man/ibv_devices.1 man/ibv_devinfo.1	\
@@ -368,6 +370,7 @@
 
 EXTRA_DIST = include/infiniband/driver.h include/infiniband/kern-abi.h \
     include/infiniband/opcode.h include/infiniband/verbs.h include/infiniband/marshall.h \
+	 include/infiniband/ofa_solaris.h \
     include/infiniband/sa-kern-abi.h include/infiniband/sa.h \
     src/ibverbs.h examples/pingpong.h \
     src/libibverbs.map libibverbs.spec.in $(man_MANS)
@@ -440,8 +443,8 @@
 	  else :; fi; \
 	done; \
 	test -z "$$list2" || { \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) -m 755 $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) -m 755 $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
 	}
 
 uninstall-libLTLIBRARIES:
@@ -486,8 +489,8 @@
 	while read type dir files; do \
 	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
 	    test -z "$$files" || { \
-	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
-	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) -m 755 $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) -m 755 $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
 	    } \
 	; done
 
@@ -554,6 +557,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/src_libibverbs_la-memory.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/src_libibverbs_la-sysfs.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/src_libibverbs_la-verbs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/src_libibverbs_la-solaris.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srq_pingpong.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uc_pingpong.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ud_pingpong.Po@am__quote@
@@ -654,6 +658,14 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libibverbs_la_CFLAGS) $(CFLAGS) -c -o src_libibverbs_la-enum_strs.lo `test -f 'src/enum_strs.c' || echo '$(srcdir)/'`src/enum_strs.c
 
+src_libibverbs_la-solaris.lo: src/solaris_compatibility.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libibverbs_la_CFLAGS) $(CFLAGS) -MT src_libibverbs_la-solaris.lo -MD -MP -MF $(DEPDIR)/src_libibverbs_la-solaris.Tpo -c -o src_libibverbs_la-solaris.lo `test -f 'src/solaris_compatibility.c' || echo '$(srcdir)/'`src/solaris_compatibility.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_libibverbs_la-solaris.Tpo $(DEPDIR)/src_libibverbs_la-solaris.Plo
+@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='src/solaris_compatibility.c' object='src_libibverbs_la-solaris.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libibverbs_la_CFLAGS) $(CFLAGS) -c -o src_libibverbs_la-solaris.lo `test -f 'src/solaris_compatibility.c' || echo '$(srcdir)/'`src/solaris_compatibility.c
+
 asyncwatch.o: examples/asyncwatch.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT asyncwatch.o -MD -MP -MF $(DEPDIR)/asyncwatch.Tpo -c -o asyncwatch.o `test -f 'examples/asyncwatch.c' || echo '$(srcdir)/'`examples/asyncwatch.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/asyncwatch.Tpo $(DEPDIR)/asyncwatch.Po
@@ -669,7 +681,6 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	source='examples/asyncwatch.c' object='asyncwatch.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o asyncwatch.obj `if test -f 'examples/asyncwatch.c'; then $(CYGPATH_W) 'examples/asyncwatch.c'; else $(CYGPATH_W) '$(srcdir)/examples/asyncwatch.c'; fi`
-
 device_list.o: examples/device_list.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT device_list.o -MD -MP -MF $(DEPDIR)/device_list.Tpo -c -o device_list.o `test -f 'examples/device_list.c' || echo '$(srcdir)/'`examples/device_list.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/device_list.Tpo $(DEPDIR)/device_list.Po
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/uc_pingpong.c libibverbs-1.1.4/examples/uc_pingpong.c
--- /tmp/846623/libibverbs-1.1.4/examples/uc_pingpong.c	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/examples/uc_pingpong.c	Tue Aug 19 10:46:28 2014
@@ -144,7 +144,7 @@
 
 	n = getaddrinfo(servername, service, &hints, &res);
 
-	if (n < 0) {
+	if (n != 0) {
 		fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
 		free(service);
 		return NULL;
@@ -219,7 +219,7 @@
 
 	n = getaddrinfo(NULL, service, &hints, &res);
 
-	if (n < 0) {
+	if (n != 0) {
 		fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
 		free(service);
 		return NULL;
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/asyncwatch.c libibverbs-1.1.4/examples/asyncwatch.c
--- /tmp/846623/libibverbs-1.1.4/examples/asyncwatch.c	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/examples/asyncwatch.c	Fri Feb 11 04:02:18 2011
@@ -35,11 +35,72 @@
 #endif /* HAVE_CONFIG_H */
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h>
+#if !(defined(__SVR4) && defined(__sun))
 #include <endian.h>
 #include <byteswap.h>
+#endif
 
 #include <infiniband/verbs.h>
 
+#define IS_PORT_EVENT(event)				\
+	((event == IBV_EVENT_PORT_ACTIVE) ||		\
+	(event == IBV_EVENT_PORT_ERR ) ||		\
+	(event == IBV_EVENT_LID_CHANGE) ||		\
+	(event == IBV_EVENT_PKEY_CHANGE) ||		\
+	(event == IBV_EVENT_SM_CHANGE) ||		\
+	(event == IBV_EVENT_GID_CHANGE) ||		\
+	(event == IBV_EVENT_CLIENT_REREGISTER))
+
+#define IS_SM_EVENT(event)				\
+	((event == IBV_EVENT_MCG_CREATED) ||		\
+	(event == IBV_EVENT_MCG_DELETED) ||		\
+	(event == IBV_EVENT_GID_AVAIL) ||		\
+	(event == IBV_EVENT_GID_UNAVAIL))
+
+#define IS_QP_EVENT(event)				\
+	((event == IBV_EVENT_CQ_ERR) ||			\
+	(event == IBV_EVENT_QP_FATAL) ||		\
+	(event == IBV_EVENT_QP_REQ_ERR) ||		\
+	(event == IBV_EVENT_COMM_EST) ||		\
+	(event == IBV_EVENT_SQ_DRAINED) ||		\
+	(event == IBV_EVENT_PATH_MIG) ||		\
+	(event == IBV_EVENT_PATH_MIG_ERR) ||		\
+	(event == IBV_EVENT_QP_LAST_WQE_REACHED) ||	\
+	(event == IBV_EVENT_QP_ACCESS_ERR))
+
+#define IS_CQ_EVENT(event)				\
+	(event == IBV_EVENT_CQ_ERR)
+
+#define IS_SRQ_EVENT(event)				\
+	((event == IBV_EVENT_SRQ_ERR) ||		\
+	(event == IBV_EVENT_SRQ_LIMIT_REACHED))
+
+#define IS_CA_EVENT(event)				\
+	(event == IBV_EVENT_DEVICE_FATAL)
+
+
+struct ibv_device	**dev_list;
+struct ibv_context	*context;
+struct ibv_async_event	event;
+union ibv_gid		*gids = NULL;
+uint_t			num_gids = 0;
+ibv_sm_event_type_t	events;
+
+static struct option long_options[] = {
+    {"sm",		0, 0, 's'},
+    {"GUID",		0, 0, 'G'},
+    {"MCG",		0, 0, 'M'},
+    {"port",		1, 0, 'p'},
+    {0, 0, 0, 0}
+};
+
+
 static const char *event_name_str(enum ibv_event_type event_type)
 {
 	switch (event_type) {
@@ -59,7 +120,14 @@
 		return "IBV_EVENT_CLIENT_REREGISTER";
 	case IBV_EVENT_GID_CHANGE:
 		return "IBV_EVENT_GID_CHANGE";
-
+	case IBV_EVENT_MCG_CREATED:
+		return "IBV_EVENT_MCG_CREATED";
+	case IBV_EVENT_MCG_DELETED:
+		return "IBV_EVENT_MCG_DELETED";
+	case IBV_EVENT_GID_AVAIL:
+		return "IBV_EVENT_GID_AVAIL";
+	case IBV_EVENT_GID_UNAVAIL:
+		return "IBV_EVENT_GID_UNAVAIL";
 	case IBV_EVENT_CQ_ERR:
 	case IBV_EVENT_QP_FATAL:
 	case IBV_EVENT_QP_REQ_ERR:
@@ -76,15 +144,173 @@
 	}
 }
 
-int main(int argc, char *argv[])
+static void catch_signal(int sig_num)
 {
-	struct ibv_device **dev_list;
-	struct ibv_context *context;
-	struct ibv_async_event event;
+	ibv_unregister_sm_events(context, events, num_gids, gids);
+	if (gids)
+		free(gids);
+	ibv_close_device(context);
+	(void) ibv_free_device_list(dev_list);
+	exit (0);
+}
 
-	/* Force line-buffering in case stdout is redirected */
-	setvbuf(stdout, NULL, _IOLBF, 0);
+static void usage(const char *argv0)
+{
+	printf("Usage:\n");
+	printf("\n");
+	printf("Options:\n");
+	printf("[ -s, --sm<gid> ]\t\tsm event\n");
+	printf("[ -M, --M ]\t\t\tsm event for MGID (multicast)\n");
+	printf("[ -G, --G ]\t\t\tsm event for UGID (unicast)\n");
+	printf("[ -p, --port=<port> ]\t\t(default 1)\n");
+	printf("\nExamples;\n");
+	printf("ibv_asyncwatch -s\t\t# monitor event=IBV_SM_EVENT_ALL\n");
+	printf("ibv_asyncwatch -G -s\t\t# monitor event="
+	    "IBV_SM_EVENT_UGID_ALL\n");
+	printf("ibv_asyncwatch -M -s\t\t# monitor event="
+	    "IBV_SM_EVENT_MGID_ALL\n");
+	printf("ibv_asyncwatch -G -s0x0021280001a0e4d9,0x0021280001a0e4da\n");
+	printf("\t\t\t\t# monitor event=IBV_SM_EVENT_UGID\n");
+	printf("ibv_asyncwatch -M -s0xff12:4001:ffff::c:2238,");
+	printf("0xff12:ffff::38:220c\n");
+	printf("\t\t\t\t# monitor event=IBV_SM_EVENT_MGID\n");
+}
 
+
+uint_t get_gids(char *argptr, uint64_t subnet_prefix)
+{
+	char		*curr, *next;
+	char		*guid_str_p1, *guid_str_p2 = NULL;
+	int		i = 0;
+	int		data_num;
+
+	for (curr = argptr; curr; curr = next, i++) {
+		next = strchr(curr, ',');
+		if (next)
+			next++;
+        }
+	data_num = i;
+	if (data_num == 0)
+		return (0);
+
+	gids = (union ibv_gid *)calloc(data_num, sizeof (union ibv_gid));
+	guid_str_p1 = malloc(strlen(argptr));
+	strncpy(guid_str_p1, argptr, strlen(argptr));
+
+	i = 0;
+	guid_str_p2 = strtok(guid_str_p1, (const char *)",");
+	while (guid_str_p2 != NULL) {
+		gids[i].global.subnet_prefix = subnet_prefix;
+		gids[i].global.interface_id =
+		    htonll((uint64_t)strtoull(guid_str_p2, 0, 0));
+		i++;
+		guid_str_p2 = strtok(NULL, (const char *)",");
+	}
+	free (guid_str_p1);
+	return (data_num);
+}
+
+void process_one_mcg_gid(union ibv_gid *gid, char *mcg_str)
+{
+	char		*token, *token_p, half_token[3];
+	uint8_t		mcg_gid[16];
+	int		i, j = 0, num_data = -1;
+	char		*curr, *next;
+
+	/* find out how many two-byte data from command line input */
+	for (curr = mcg_str; curr; curr = next, num_data++) {
+		next = strchr(curr, ':');
+		if (next)
+			next++;
+        }
+
+	if (num_data > 8) {
+		fprintf(stderr, "Invalid MGID input format: %s\n", mcg_str);
+		exit (-1);
+	}
+
+	curr = mcg_str + 2;	/* Skip past 0x */
+	while ((token = strsep(&curr, ":")) != NULL && j < 15) {
+		if (strncmp(token, "\0", 1) == 0) {
+			/* We have :: in the input */
+			for (i = 0; i < 8 - num_data; i++) {
+				mcg_gid[j++] = 0;
+				mcg_gid[j++] = 0;
+			}
+		} else {
+			if (strlen(token) < 3) {
+				mcg_gid[j++] = 0;
+				mcg_gid[j++] =
+				    (uint8_t)strtoll(token, NULL, 16);
+			} else {
+				memset(half_token, 0, 3);
+				token_p = token;
+				if (strlen(token) == 3) {
+					strncpy(half_token, token, 1);
+					token_p += 1;
+				} else {
+					strncpy(half_token, token, 2);
+					token_p += 2;
+				}
+				mcg_gid[j++] = (uint8_t)strtol(half_token,
+				    NULL, 16);
+
+				mcg_gid[j++] = (uint8_t)strtol(token_p,
+				    NULL, 16);
+			}
+		}
+	}
+
+	memcpy(gid->raw, mcg_gid, 16);
+}
+
+uint_t get_mcgs(char *argptr, uint64_t subnet_prefix)
+{
+	char            *curr, *next;
+	char		*mcg_str_p1, *mcg_str_p2 = NULL;
+	int		i = 0;
+	int		data_num;
+
+	for (curr = argptr; curr; curr = next, i++) {
+		next = strchr(curr, ',');
+		if (next)
+			next++;
+        }
+	data_num = i;
+	if (data_num == 0)
+		return (0);
+
+	gids = (union ibv_gid *)calloc(data_num, sizeof (union ibv_gid));
+	mcg_str_p1 = malloc(strlen(argptr));
+	strncpy(mcg_str_p1, argptr, strlen(argptr));
+
+	i = 0;
+	mcg_str_p2 = strtok(mcg_str_p1, (const char *)",");
+	while (mcg_str_p2 != NULL) {
+		if (strncmp(mcg_str_p2, "0xff", 4) != 0) {
+			fprintf(stderr, "Invalid MGID input format: %s\n",
+			    mcg_str_p2);
+			exit (-1);
+		}
+		process_one_mcg_gid(&gids[i], mcg_str_p2);
+		i++;
+		mcg_str_p2 = strtok(NULL, (const char *)",");
+	}
+	free(mcg_str_p1);
+	return (data_num);
+}
+
+int main(int argc, char *argv[])
+{
+	int		c;
+	int		ret;
+	uint_t		port = 1;	/* default */
+	uint_t		do_sm_event_register = 0;
+	union ibv_gid	sgid;
+	uint64_t	subnet_prefix = 0ULL;
+	int		mcgflag = 0;
+	int		guidflag = 0;
+
 	dev_list = ibv_get_device_list(NULL);
 	if (!dev_list) {
 		perror("Failed to get IB devices list");
@@ -103,19 +329,111 @@
 		return 1;
 	}
 
-	printf("%s: async event FD %d\n",
+	printf("\n%s: async event FD %d\n\n",
 	       ibv_get_device_name(*dev_list), context->async_fd);
 
+	ibv_query_gid(context, port, 0, &sgid);
+	subnet_prefix = sgid.global.subnet_prefix;
+
+	while ((c = getopt_long(argc, argv, "p:GMs::t:", long_options, NULL))
+	    != -1) {
+		switch(c) {
+			case 'G':
+				guidflag = 1;
+				break;
+			case 'M':
+				mcgflag = 1;
+				break;
+			case 's':
+				do_sm_event_register = 1;
+				if (mcgflag == 1)
+					num_gids =
+					    get_mcgs(optarg, subnet_prefix);
+				else
+					num_gids =
+					    get_gids(optarg, subnet_prefix);
+				break;
+			case 'p':
+				port = strtol(optarg, NULL, 0);
+				ibv_query_gid(context, port, 0, &sgid);
+				subnet_prefix = sgid.global.subnet_prefix;
+				break;
+			default:
+				usage(argv[0]);
+				return 1;
+		}
+	}
+
+	/* Force line-buffering in case stdout is redirected */
+	setvbuf(stdout, NULL, _IOLBF, 0);
+
+	if (num_gids) {
+		if (mcgflag)
+			events = IBV_SM_EVENT_MGID;
+		else
+			events = IBV_SM_EVENT_UGID;
+	} else {
+		if (mcgflag && guidflag)
+			events = IBV_SM_EVENT_ALL;
+		else if (mcgflag)
+			events = IBV_SM_EVENT_MGID_ALL;
+		else if (guidflag)
+			events = IBV_SM_EVENT_UGID_ALL;
+		else
+			events = IBV_SM_EVENT_ALL;
+	}
+
+	if (do_sm_event_register)
+		ret = ibv_register_sm_events(context, events, num_gids, gids);
+
+	(void) signal(SIGINT, catch_signal);
+
 	while (1) {
 		if (ibv_get_async_event(context, &event))
 			return 1;
 
-		printf("  event_type %s (%d), port %d\n",
-		       event_name_str(event.event_type),
-		       event.event_type, event.element.port_num);
+		if (IS_PORT_EVENT(event.event_type))
+			printf("Event: %s (%d), port %d\n",
+			    event_name_str(event.event_type),
+			    event.event_type, event.element.port_num);
+		else if (IS_SM_EVENT(event.event_type))
+			printf("Event: %s (%d), gid " \
+			    "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"\
+			    "%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+			    event_name_str(event.event_type), event.event_type,
+			    event.element.gid.raw[0], event.element.gid.raw[1],
+			    event.element.gid.raw[2], event.element.gid.raw[3],
+			    event.element.gid.raw[4], event.element.gid.raw[5],
+			    event.element.gid.raw[6], event.element.gid.raw[7],
+			    event.element.gid.raw[8], event.element.gid.raw[9],
+			    event.element.gid.raw[10],
+			    event.element.gid.raw[11],
+			    event.element.gid.raw[12],
+			    event.element.gid.raw[13],
+			    event.element.gid.raw[14],
+			    event.element.gid.raw[15]);
+		else if (IS_QP_EVENT(event.event_type))
+			printf("Event: %s (%d) QPN %d\n",
+			    event_name_str(event.event_type), event.event_type,
+			    event.element.qp->qp_num);
+		else if (IS_CQ_EVENT(event.event_type))
+			printf("Event: %s (%d) CQE %d\n",
+			    event_name_str(event.event_type), event.event_type,
+			    event.element.cq->cqe);
+		else if (IS_SRQ_EVENT(event.event_type))
+			printf("Event: %s (%d) SRQ %d\n",
+			    event_name_str(event.event_type), event.event_type,
+			    event.element.srq->handle);
+		else
+			printf("Event: %s (%d)\n",
+			    event_name_str(event.event_type), event.event_type);
 
 		ibv_ack_async_event(&event);
-	}
 
+		if (event.event_type == IBV_EVENT_GID_AVAIL) {
+			ret = ibv_gid_reachable(context, port,
+			    &event.element.gid, 0);
+		}
+	}
 	return 0;
 }
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/srq_pingpong.c libibverbs-1.1.4/examples/srq_pingpong.c
--- /tmp/846623/libibverbs-1.1.4/examples/srq_pingpong.c	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/examples/srq_pingpong.c	Wed Jun  8 09:46:34 2011
@@ -165,8 +165,13 @@
 
 	n = getaddrinfo(servername, service, &hints, &res);
 
-	if (n < 0) {
-		fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
+	if (n != 0) {
+		if (n == EAI_NONAME)
+			fprintf(stderr,
+			    "Name or service not known for %s:%d\n", servername, port);
+		else
+			fprintf(stderr,
+			    "%s for %s:%d\n", gai_strerror(n), servername, port);
 		free(service);
 		return NULL;
 	}
@@ -253,7 +258,7 @@
 
 	n = getaddrinfo(NULL, service, &hints, &res);
 
-	if (n < 0) {
+	if (n != 0) {
 		fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
 		free(service);
 		return NULL;
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/ud_pingpong.c libibverbs-1.1.4/examples/ud_pingpong.c
--- /tmp/846623/libibverbs-1.1.4/examples/ud_pingpong.c	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/examples/ud_pingpong.c	Wed Jun  8 09:46:34 2011
@@ -143,8 +143,13 @@
 
 	n = getaddrinfo(servername, service, &hints, &res);
 
-	if (n < 0) {
-		fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
+	if (n != 0) {
+		if (n == EAI_NONAME)
+			fprintf(stderr,
+			    "Name or service not known for %s:%d\n", servername, port);
+		else
+			fprintf(stderr,
+			    "%s for %s:%d\n", gai_strerror(n), servername, port);
 		free(service);
 		return NULL;
 	}
@@ -217,7 +222,7 @@
 
 	n = getaddrinfo(NULL, service, &hints, &res);
 
-	if (n < 0) {
+	if (n != 0) {
 		fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
 		free(service);
 		return NULL;
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/rc_pingpong.c libibverbs-1.1.4/examples/rc_pingpong.c
--- /tmp/846623/libibverbs-1.1.4/examples/rc_pingpong.c	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/examples/rc_pingpong.c	Wed Jun  8 09:46:34 2011
@@ -155,8 +155,13 @@
 
 	n = getaddrinfo(servername, service, &hints, &res);
 
-	if (n < 0) {
-		fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port);
+	if (n != 0) {
+		if (n == EAI_NONAME)
+			fprintf(stderr,
+			    "Name or service not known for %s:%d\n", servername, port);
+		else
+			fprintf(stderr,
+			    "%s for %s:%d\n", gai_strerror(n), servername, port);
 		free(service);
 		return NULL;
 	}
@@ -230,7 +235,7 @@
 
 	n = getaddrinfo(NULL, service, &hints, &res);
 
-	if (n < 0) {
+	if (n != 0) {
 		fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
 		free(service);
 		return NULL;
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/device_list.c libibverbs-1.1.4/examples/device_list.c
--- /tmp/846623/libibverbs-1.1.4/examples/device_list.c	Sun Nov  1 06:47:19 2009
+++ libibverbs-1.1.4/examples/device_list.c	Fri Feb 11 04:02:18 2011
@@ -36,16 +36,32 @@
 
 #include <stdio.h>
 
+#if !(defined(__SVR4) && defined(__sun))
 #include <endian.h>
 #include <byteswap.h>
+#endif
 
+#include <stdlib.h>
+#include <string.h>
 #include <infiniband/verbs.h>
 #include <infiniband/arch.h>
 
+/*
+ * Structure to hold the data printed by ibv_devices.
+ */
+typedef struct dev_print_s {
+	char			name[24];
+	unsigned long long	guid;
+	uint8_t			is_pf;
+} dev_print_t;
+
 int main(int argc, char *argv[])
 {
 	struct ibv_device **dev_list;
 	int num_devices, i;
+	unsigned long long	guid_external;
+	dev_print_t	*dp;
+	int	print_col = 0;
 
 	dev_list = ibv_get_device_list(&num_devices);
 	if (!dev_list) {
@@ -53,15 +69,45 @@
 		return 1;
 	}
 
-	printf("    %-16s\t   node GUID\n", "device");
-	printf("    %-16s\t----------------\n", "------");
+	dp = (dev_print_t *)malloc(sizeof(dev_print_t) * num_devices);
 
-	for (i = 0; i < num_devices; ++i) {
-		printf("    %-16s\t%016llx\n",
-		       ibv_get_device_name(dev_list[i]),
-		       (unsigned long long) ntohll(ibv_get_device_guid(dev_list[i])));
+	for (i = (num_devices - 1); i >= 0; --i) {
+		strcpy(dp[i].name, ibv_get_device_name(dev_list[i]));
+
+		dp[i].guid = (unsigned long long) ntohll(ibv_get_device_guid(dev_list[i]));
+		guid_external = (unsigned long long) ntohll(ibv_get_device_guid_external(dev_list[i]));
+		if (dp[i].guid != guid_external) {
+			print_col = 1;
+			dp[i].is_pf = 0;
+		} else
+			dp[i].is_pf = 1;
 	}
 
+	if (print_col) {
+		printf("    %-16s\t   node GUID\t        type\n", "device");
+		printf("    %-16s\t----------------\t----\n", "------");
+		/* First print PFs */
+		for (i = (num_devices - 1); i >= 0; --i) {
+			if (dp[i].is_pf)
+				printf("    %-16s\t%016llx\t %s\n",
+					dp[i].name, dp[i].guid, "PF");
+		}
+		/* print VFs */
+		for (i = (num_devices - 1); i >= 0; --i) {
+			if (!dp[i].is_pf)
+				printf("    %-16s\t%016llx\t %s\n",
+					dp[i].name, dp[i].guid, "VF");
+		}
+	} else {
+		printf("    %-16s\t   node GUID\n", "device");
+		printf("    %-16s\t----------------\n", "------");
+		for (i = (num_devices - 1); i >= 0; --i) {
+			printf("    %-16s\t%016llx\n",
+				dp[i].name, dp[i].guid);
+		}
+	}
+	free(dp);
+
 	ibv_free_device_list(dev_list);
 
 	return 0;
diff -r -u /tmp/846623/libibverbs-1.1.4/examples/devinfo.c libibverbs-1.1.4/examples/devinfo.c
--- /tmp/846623/libibverbs-1.1.4/examples/devinfo.c	Thu Mar 10 06:58:21 2011
+++ libibverbs-1.1.4/examples/devinfo.c	Fri Feb 11 04:02:19 2011
@@ -41,8 +41,10 @@
 #include <string.h>
 #include <getopt.h>
 #include <netinet/in.h>
+#if !(defined(__SVR4) && defined(__sun))
 #include <endian.h>
 #include <byteswap.h>
+#endif
 
 #include <infiniband/verbs.h>
 #include <infiniband/driver.h>