[ofa-general] [PATCH] opensm: consolidate SA response sending code over SA processors

Sasha Khapyorsky sashak at voltaire.com
Sun Mar 2 12:05:05 PST 2008


Consolidate SA response sending code over SA processors in single
osm_sa_respond() function. Drop a lot of duplicated code.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 opensm/include/opensm/osm_sa.h          |   31 +++++
 opensm/opensm/osm_sa.c                  |  116 +++++++++++++++++-
 opensm/opensm/osm_sa_guidinfo_record.c  |  130 +--------------------
 opensm/opensm/osm_sa_informinfo.c       |  180 ++++------------------------
 opensm/opensm/osm_sa_lft_record.c       |  132 +--------------------
 opensm/opensm/osm_sa_link_record.c      |  145 +----------------------
 opensm/opensm/osm_sa_mcmember_record.c  |  203 +++++--------------------------
 opensm/opensm/osm_sa_mft_record.c       |  132 +--------------------
 opensm/opensm/osm_sa_multipath_record.c |  104 ++--------------
 opensm/opensm/osm_sa_node_record.c      |  121 +------------------
 opensm/opensm/osm_sa_path_record.c      |  139 +---------------------
 opensm/opensm/osm_sa_pkey_record.c      |  133 +--------------------
 opensm/opensm/osm_sa_portinfo_record.c  |  142 +--------------------
 opensm/opensm/osm_sa_service_record.c   |  167 +++-----------------------
 opensm/opensm/osm_sa_slvl_record.c      |  133 +--------------------
 opensm/opensm/osm_sa_sminfo_record.c    |  133 +--------------------
 opensm/opensm/osm_sa_sw_info_record.c   |  123 +------------------
 opensm/opensm/osm_sa_vlarb_record.c     |  133 +--------------------
 18 files changed, 244 insertions(+), 2153 deletions(-)

diff --git a/opensm/include/opensm/osm_sa.h b/opensm/include/opensm/osm_sa.h
index a150695..f4f751b 100644
--- a/opensm/include/opensm/osm_sa.h
+++ b/opensm/include/opensm/osm_sa.h
@@ -398,6 +398,37 @@ osm_sa_send_error(IN osm_sa_t * sa,
 *	SA object
 *********/
 
+/****f* OpenSM: SA/osm_sa_respond
+* NAME
+*	osm_sa_respond
+*
+* DESCRIPTION
+*	Sends SA MAD response
+*/
+void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size,
+		    cl_qlist_t *list);
+/*
+* PARAMETERS
+*	sa
+*		[in] Pointer to an osm_sa_t object.
+*
+*	p_madw
+*		[in] Original MAD to which the response must be sent.
+*
+*	attr_size
+*		[in] Size of this SA attribute.
+*
+*	list
+*		[in] List of attribute to respond - it will be freed after
+*		sending.
+*
+* RETURN VALUES
+*	None.
+*
+* SEE ALSO
+*	SA object
+*********/
+
 struct _osm_opensm_t;
 /****f* OpenSM: SA/osm_sa_db_file_dump
 * NAME
diff --git a/opensm/opensm/osm_sa.c b/opensm/opensm/osm_sa.c
index c557876..4edce47 100644
--- a/opensm/opensm/osm_sa.c
+++ b/opensm/opensm/osm_sa.c
@@ -360,7 +360,7 @@ osm_sa_send_error(IN osm_sa_t * sa,
 				       &p_madw->mad_addr);
 
 	if (p_resp_madw == NULL) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2301: "
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C07: "
 			"Unable to acquire response MAD\n");
 		goto Exit;
 	}
@@ -399,6 +399,120 @@ Exit:
 	OSM_LOG_EXIT(sa->p_log);
 }
 
+void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size,
+		    cl_qlist_t *list)
+{
+	struct item_data {
+		cl_list_item_t list;
+		char data[0];
+	};
+	cl_list_item_t *item;
+	osm_madw_t *resp_madw;
+	ib_sa_mad_t *sa_mad, *resp_sa_mad;
+	unsigned num_rec, i;
+#ifndef VENDOR_RMPP_SUPPORT
+	unsigned trim_num_rec;
+#endif
+	void *p;
+
+	sa_mad = osm_madw_get_sa_mad_ptr(madw);
+	num_rec = cl_qlist_count(list);
+
+	/*
+	 * C15-0.1.30:
+	 * If we do a SubnAdmGet and got more than one record it is an error!
+	 */
+	if (sa_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C05: "
+			"Got more than one record for SubnAdmGet (%u)\n",
+			num_rec);
+		osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
+		goto Exit;
+	}
+
+#ifndef VENDOR_RMPP_SUPPORT
+	trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / attr_size;
+	if (trim_num_rec < num_rec) {
+		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
+			"Number of records:%u trimmed to:%u to fit in one MAD\n",
+			num_rec, trim_num_rec);
+		num_rec = trim_num_rec;
+	}
+#endif
+
+	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
+
+	if (sa_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
+		osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RECORDS);
+		goto Exit;
+	}
+
+	/*
+	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
+	 */
+	resp_madw = osm_mad_pool_get(sa->p_mad_pool, madw->h_bind,
+				     num_rec * attr_size + IB_SA_MAD_HDR_SIZE,
+				     &madw->mad_addr);
+	if (!resp_madw) {
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C06: "
+			"osm_mad_pool_get failed\n");
+		osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RESOURCES);
+		goto Exit;
+	}
+
+	resp_sa_mad = osm_madw_get_sa_mad_ptr(resp_madw);
+
+	/*
+	   Copy the MAD header back into the response mad.
+	   Set the 'R' bit and the payload length,
+	   Then copy all records from the list into the response payload.
+	 */
+
+	memcpy(resp_sa_mad, sa_mad, IB_SA_MAD_HDR_SIZE);
+	if (resp_sa_mad->method == IB_MAD_METHOD_SET)
+		resp_sa_mad->method = IB_MAD_METHOD_GET;
+	resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
+	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
+	resp_sa_mad->sm_key = 0;
+
+	/* Fill in the offset (paylen will be done by the rmpp SAR) */
+	resp_sa_mad->attr_offset = ib_get_attr_offset(attr_size);
+
+	p = ib_sa_mad_get_payload_ptr(resp_sa_mad);
+
+#ifndef VENDOR_RMPP_SUPPORT
+	/* we support only one packet RMPP - so we will set the first and
+	   last flags for gettable */
+	if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
+		resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
+		resp_sa_mad->rmpp_flags =
+		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
+		    IB_RMPP_FLAG_ACTIVE;
+	}
+#else
+	/* forcefully define the packet as RMPP one */
+	if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
+		resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
+#endif
+
+	for (i = 0; i < num_rec; i++) {
+		item = cl_qlist_remove_head(list);
+		memcpy(p, ((struct item_data *)item)->data, attr_size);
+		p += attr_size;
+	}
+
+	osm_sa_vendor_send(resp_madw->h_bind, resp_madw, FALSE, sa->p_subn);
+
+	osm_dump_sa_mad(sa->p_log, resp_sa_mad, OSM_LOG_FRAMES);
+Exit:
+	/* need to set the mem free ... */
+	item = cl_qlist_remove_head(list);
+	while (item != cl_qlist_end(list)) {
+		free(item);
+		item = cl_qlist_remove_head(list);
+	}
+}
+
 /**********************************************************************
  **********************************************************************/
 /*
diff --git a/opensm/opensm/osm_sa_guidinfo_record.c b/opensm/opensm/osm_sa_guidinfo_record.c
index 76332bd..43f249a 100644
--- a/opensm/opensm/osm_sa_guidinfo_record.c
+++ b/opensm/opensm/osm_sa_guidinfo_record.c
@@ -314,16 +314,7 @@ void osm_gir_rcv_process(IN void *ctx, IN void *data)
 	const ib_sa_mad_t *p_rcvd_mad;
 	const ib_guidinfo_record_t *p_rcvd_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_guidinfo_record_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_gir_search_ctxt_t context;
-	osm_gir_item_t *p_rec_item;
 	osm_physp_t *p_req_physp;
 
 	CL_ASSERT(sa);
@@ -376,126 +367,7 @@ void osm_gir_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5103: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_gir_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_gir_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_gir_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_guidinfo_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_guidinfo_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5106: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_gir_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_guidinfo_record_t));
-
-	p_resp_rec = (ib_guidinfo_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item = (osm_gir_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_guidinfo_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_informinfo.c b/opensm/opensm/osm_sa_informinfo.c
index d231102..f91d0ab 100644
--- a/opensm/opensm/osm_sa_informinfo.c
+++ b/opensm/opensm/osm_sa_informinfo.c
@@ -218,12 +218,10 @@ Set(InformInfo) request.
 **********************************************************************/
 static void
 __osm_infr_rcv_respond(IN osm_sa_t * sa,
-		       IN const osm_madw_t * const p_madw)
+		       IN osm_madw_t * const p_madw)
 {
-	osm_madw_t *p_resp_madw;
-	const ib_sa_mad_t *p_sa_mad;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_inform_info_t *p_resp_infr;
+	cl_qlist_t rec_list;
+	osm_iir_item_t *item;
 
 	OSM_LOG_ENTER(sa->p_log);
 
@@ -232,31 +230,21 @@ __osm_infr_rcv_respond(IN osm_sa_t * sa,
 			"Generating successful InformInfo response\n");
 	}
 
-	/*
-	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool,
-				       p_madw->h_bind,
-				       MAD_BLOCK_SIZE, &p_madw->mad_addr);
-	if (!p_resp_madw) {
+	item = malloc(sizeof(*item));
+	if (!item) {
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4303: "
-			"Unable to allocate MAD\n");
+			"rec_item alloc failed\n");
 		goto Exit;
 	}
 
-	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/* copy the request InformInfo */
-	memcpy(p_resp_sa_mad, p_sa_mad, MAD_BLOCK_SIZE);
-	p_resp_sa_mad->method = IB_MAD_METHOD_GET_RESP;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
+	memcpy(&item->rec,
+	       ib_sa_mad_get_payload_ptr(osm_madw_get_sa_mad_ptr(p_madw)),
+	       sizeof(item->rec));
 
-	p_resp_infr =
-	    (ib_inform_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
+	cl_qlist_init(&rec_list);
+	cl_qlist_insert_tail(&rec_list, &item->list_item);
 
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
@@ -351,22 +339,14 @@ Received a Get(InformInfoRecord) or GetTable(InformInfoRecord) MAD
 **********************************************************************/
 static void
 osm_infr_rcv_process_get_method(IN osm_sa_t * sa,
-				IN const osm_madw_t * const p_madw)
+				IN osm_madw_t * const p_madw)
 {
 	ib_sa_mad_t *p_rcvd_mad;
 	const ib_inform_info_record_t *p_rcvd_rec;
-	ib_inform_info_record_t *p_resp_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i, j;
 	osm_iir_search_ctxt_t context;
-	osm_iir_item_t *p_rec_item;
 	osm_physp_t *p_req_physp;
+	osm_iir_item_t *item;
 
 	OSM_LOG_ENTER(sa->p_log);
 
@@ -416,131 +396,15 @@ osm_infr_rcv_process_get_method(IN osm_sa_t * sa,
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 430A: "
-				"More than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_iir_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_iir_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_iir_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we limit the number of records to a single packet */
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_inform_info_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
+	/* clear reserved and pad fields in InformInfoRecord */
+	for (item = (osm_iir_item_t *) cl_qlist_head(&rec_list);
+	     item != (osm_iir_item_t *) cl_qlist_end(&rec_list);
+	     item = (osm_iir_item_t *)cl_qlist_next(&item->list_item)) {
+		memset(item->rec.reserved, 0, sizeof(item->rec.reserved));
+		memset(item->rec.pad, 0, sizeof(item->rec.pad));
 	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool,
-				       p_madw->h_bind,
-				       num_rec *
-				       sizeof(ib_inform_info_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 430B: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_iir_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_inform_info_record_t));
-
-	p_resp_rec = (ib_inform_info_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item = (osm_iir_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec) {
-			*p_resp_rec = p_rec_item->rec;
-			/* clear reserved and pad fields in InformInfoRecord */
-			for (j = 0; j < 6; j++)
-				p_resp_rec->reserved[j] = 0;
-			for (j = 0; j < 4; j++)
-				p_resp_rec->pad[j] = 0;
-		}
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
 
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
@@ -551,7 +415,7 @@ Received a Set(InformInfo) MAD
 **********************************************************************/
 static void
 osm_infr_rcv_process_set_method(IN osm_sa_t * sa,
-				IN const osm_madw_t * const p_madw)
+				IN osm_madw_t * const p_madw)
 {
 	ib_sa_mad_t *p_sa_mad;
 	ib_inform_info_t *p_recvd_inform_info;
diff --git a/opensm/opensm/osm_sa_lft_record.c b/opensm/opensm/osm_sa_lft_record.c
index c516231..82bb63c 100644
--- a/opensm/opensm/osm_sa_lft_record.c
+++ b/opensm/opensm/osm_sa_lft_record.c
@@ -219,17 +219,8 @@ void osm_lftr_rcv_process(IN void *ctx, IN void *data)
 	osm_madw_t *p_madw = data;
 	const ib_sa_mad_t *p_rcvd_mad;
 	const ib_lft_record_t *p_rcvd_rec;
-	ib_lft_record_t *p_resp_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_lftr_search_ctxt_t context;
-	osm_lftr_item_t *p_rec_item;
 	osm_physp_t *p_req_physp;
 
 	CL_ASSERT(sa);
@@ -279,128 +270,7 @@ void osm_lftr_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4409: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_lftr_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_lftr_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_lftr_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we limit the number of records to a single packet */
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_lft_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_lft_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4410: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_lftr_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_lft_record_t));
-
-	p_resp_rec =
-	    (ib_lft_record_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_lftr_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_lft_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_link_record.c b/opensm/opensm/osm_sa_link_record.c
index 2badc9d..31abf43 100644
--- a/opensm/opensm/osm_sa_link_record.c
+++ b/opensm/opensm/osm_sa_link_record.c
@@ -443,142 +443,6 @@ Exit:
 
 /**********************************************************************
  **********************************************************************/
-static void
-__osm_lr_rcv_respond(IN osm_sa_t * sa,
-		     IN const osm_madw_t * const p_madw,
-		     IN cl_qlist_t * const p_list)
-{
-	osm_madw_t *p_resp_madw;
-	const ib_sa_mad_t *p_sa_mad;
-	ib_sa_mad_t *p_resp_sa_mad;
-	size_t num_rec, num_copied;
-#ifndef VENDOR_RMPP_SUPPORT
-	size_t trim_num_rec;
-#endif
-	ib_link_record_t *p_resp_lr;
-	osm_lr_item_t *p_lr_item;
-	const ib_sa_mad_t *p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
-
-	OSM_LOG_ENTER(sa->p_log);
-
-	num_rec = cl_qlist_count(p_list);
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1806: "
-			"Got more than one record for SubnAdmGet (%zu)\n",
-			num_rec);
-		osm_sa_send_error(sa, p_madw,
-				  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-		/* need to set the mem free ... */
-		p_lr_item = (osm_lr_item_t *) cl_qlist_remove_head(p_list);
-		while (p_lr_item != (osm_lr_item_t *) cl_qlist_end(p_list)) {
-			free(p_lr_item);
-			p_lr_item =
-			    (osm_lr_item_t *) cl_qlist_remove_head(p_list);
-		}
-
-		goto Exit;
-	}
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_link_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG)) {
-		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-			"Generating response with %zu records", num_rec);
-	}
-
-	/*
-	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_link_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1802: "
-			"Unable to allocate MAD\n");
-		/* Release the quick pool items */
-		p_lr_item = (osm_lr_item_t *) cl_qlist_remove_head(p_list);
-		while (p_lr_item != (osm_lr_item_t *) cl_qlist_end(p_list)) {
-			free(p_lr_item);
-			p_lr_item =
-			    (osm_lr_item_t *) cl_qlist_remove_head(p_list);
-		}
-
-		goto Exit;
-	}
-
-	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/* Copy the header from the request to response */
-	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_link_record_t));
-	/* C15-0.1.5 - always return SM_Key = 0 (table table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	p_resp_lr =
-	    (ib_link_record_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-	if ((p_rcvd_mad->method == IB_MAD_METHOD_GET) && (num_rec == 0)) {
-		p_resp_sa_mad->status = IB_SA_MAD_STATUS_NO_RECORDS;
-		memset(p_resp_lr, 0, sizeof(*p_resp_lr));
-	} else {
-		p_lr_item = (osm_lr_item_t *) cl_qlist_remove_head(p_list);
-		/* we need to track the number of copied items so we can
-		 * stop the copy - but clear them all
-		 */
-		num_copied = 0;
-		while (p_lr_item != (osm_lr_item_t *) cl_qlist_end(p_list)) {
-			/*  Copy the Link Records from the list into the MAD */
-			/*  only if we did not go over the mad size (since we might trimmed it) */
-			if (num_copied < num_rec) {
-				*p_resp_lr = p_lr_item->link_rec;
-				num_copied++;
-			}
-			free(p_lr_item);
-			p_resp_lr++;
-			p_lr_item =
-			    (osm_lr_item_t *) cl_qlist_remove_head(p_list);
-		}
-	}
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
-
-Exit:
-	OSM_LOG_EXIT(sa->p_log);
-}
-
-/**********************************************************************
- **********************************************************************/
 void osm_lr_rcv_process(IN void *context, IN void *data)
 {
 	osm_sa_t *sa = context;
@@ -641,15 +505,8 @@ void osm_lr_rcv_process(IN void *context, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	if (cl_qlist_count(&lr_list) == 0 &&
-	    p_sa_mad->method == IB_MAD_METHOD_GET) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	__osm_lr_rcv_respond(sa, p_madw, &lr_list);
+	osm_sa_respond(sa, p_madw, sizeof(ib_link_record_t), &lr_list);
 
 Exit:
-
 	OSM_LOG_EXIT(sa->p_log);
 }
diff --git a/opensm/opensm/osm_sa_mcmember_record.c b/opensm/opensm/osm_sa_mcmember_record.c
index 1de05e7..136ba77 100644
--- a/opensm/opensm/osm_sa_mcmember_record.c
+++ b/opensm/opensm/osm_sa_mcmember_record.c
@@ -334,59 +334,35 @@ Generate the response MAD
 **********************************************************************/
 static void
 __osm_mcmr_rcv_respond(IN osm_sa_t * sa,
-		       IN const osm_madw_t * const p_madw,
+		       IN osm_madw_t * const p_madw,
 		       IN ib_member_rec_t * p_mcmember_rec)
 {
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_sa_mad, *p_resp_sa_mad;
-	ib_member_rec_t *p_resp_mcmember_rec;
+	cl_qlist_t rec_list;
+	osm_mcmr_item_t *item;
 
 	OSM_LOG_ENTER(sa->p_log);
 
-	/*
-	 *  Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool,
-				       p_madw->h_bind,
-				       sizeof(ib_member_rec_t) +
-				       IB_SA_MAD_HDR_SIZE,
-				       osm_madw_get_mad_addr_ptr(p_madw));
-	if (!p_resp_madw)
+	item = malloc(sizeof(*item));
+	if (!item) {
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B16: "
+			"rec_item alloc failed\n");
 		goto Exit;
-
-	p_resp_sa_mad = (ib_sa_mad_t *) p_resp_madw->p_mad;
-	p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad;
-	/*  Copy the MAD header back into the response mad */
-	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
-	/*  based on the current method decide about the response: */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GET ||
-	    p_resp_sa_mad->method == IB_MAD_METHOD_SET)
-		p_resp_sa_mad->method = IB_MAD_METHOD_GET_RESP;
-	else if (p_resp_sa_mad->method == IB_MAD_METHOD_DELETE)
-		p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	else {
-		CL_ASSERT(p_resp_sa_mad->method == 0);
 	}
 
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_member_rec_t));
-	p_resp_mcmember_rec = (ib_member_rec_t *) & p_resp_sa_mad->data;
-
-	*p_resp_mcmember_rec = *p_mcmember_rec;
+	item->rec = *p_mcmember_rec;
 
 	/* Fill in the mtu, rate, and packet lifetime selectors */
-	p_resp_mcmember_rec->mtu &= 0x3f;
-	p_resp_mcmember_rec->mtu |= 2 << 6;	/* exactly */
-	p_resp_mcmember_rec->rate &= 0x3f;
-	p_resp_mcmember_rec->rate |= 2 << 6;	/* exactly */
-	p_resp_mcmember_rec->pkt_life &= 0x3f;
-	p_resp_mcmember_rec->pkt_life |= 2 << 6;	/* exactly */
+	item->rec.mtu &= 0x3f;
+	item->rec.mtu |= 2 << 6;	/* exactly */
+	item->rec.rate &= 0x3f;
+	item->rec.rate |= 2 << 6;	/* exactly */
+	item->rec.pkt_life &= 0x3f;
+	item->rec.pkt_life |= 2 << 6;	/* exactly */
+
+	cl_qlist_init(&rec_list);
+	cl_qlist_insert_tail(&rec_list, &item->list_item);
 
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_member_rec_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
@@ -1188,7 +1164,7 @@ Process a request for leaving the group
 **********************************************************************/
 static void
 __osm_mcmr_rcv_leave_mgrp(IN osm_sa_t * sa,
-			  IN const osm_madw_t * const p_madw)
+			  IN osm_madw_t * const p_madw)
 {
 	boolean_t valid;
 	osm_mgrp_t *p_mgrp;
@@ -1307,7 +1283,7 @@ Exit:
 **********************************************************************/
 static void
 __osm_mcmr_rcv_join_mgrp(IN osm_sa_t * sa,
-			 IN const osm_madw_t * const p_madw)
+			 IN osm_madw_t * const p_madw)
 {
 	boolean_t valid;
 	osm_mgrp_t *p_mgrp = NULL;
@@ -1804,21 +1780,12 @@ Exit:
 **********************************************************************/
 static void
 __osm_mcmr_query_mgrp(IN osm_sa_t * sa,
-		      IN const osm_madw_t * const p_madw)
+		      IN osm_madw_t * const p_madw)
 {
 	const ib_sa_mad_t *p_rcvd_mad;
 	const ib_member_rec_t *p_rcvd_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_member_rec_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_sa_mcmr_search_ctxt_t context;
-	osm_mcmr_item_t *p_rec_item;
 	ib_net64_t comp_mask;
 	osm_physp_t *p_req_physp;
 	boolean_t trusted_req;
@@ -1862,108 +1829,6 @@ __osm_mcmr_query_mgrp(IN osm_sa_t * sa,
 
 	CL_PLOCK_RELEASE(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B05: "
-			"Got more than one record for SubnAdmGet (%u)\n",
-			num_rec);
-		osm_sa_send_error(sa, p_madw,
-				  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-		/* need to set the mem free ... */
-		p_rec_item =
-		    (osm_mcmr_item_t *) cl_qlist_remove_head(&rec_list);
-		while (p_rec_item !=
-		       (osm_mcmr_item_t *) cl_qlist_end(&rec_list)) {
-			free(p_rec_item);
-			p_rec_item =
-			    (osm_mcmr_item_t *) cl_qlist_remove_head(&rec_list);
-		}
-
-		goto Exit;
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_member_rec_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_member_rec_t) +
-				       IB_SA_MAD_HDR_SIZE,
-				       osm_madw_get_mad_addr_ptr(p_madw));
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B16: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_mcmr_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_member_rec_t));
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	p_resp_rec =
-	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
 	/*
 	   p923 - The PortGID, JoinState and ProxyJoin shall be zero,
 	   except in the case of a trusted request.
@@ -1972,26 +1837,18 @@ __osm_mcmr_query_mgrp(IN osm_sa_t * sa,
 	   sm_key.
 	 */
 
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_mcmr_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec) {
-			*p_resp_rec = p_rec_item->rec;
-			if (trusted_req == FALSE) {
-				memset(&p_resp_rec->port_gid, 0,
-				       sizeof(ib_gid_t));
-				ib_member_set_join_state(p_resp_rec, 0);
-				p_resp_rec->proxy_join = 0;
-			}
+	if (!p_rcvd_mad->sm_key) {
+		osm_mcmr_item_t *item;
+		for (item = (osm_mcmr_item_t *) cl_qlist_head(&rec_list);
+		     item != (osm_mcmr_item_t *) cl_qlist_end(&rec_list);
+		     item = (osm_mcmr_item_t *)cl_qlist_next(&item->list_item)) {
+			memset(&item->rec.port_gid, 0, sizeof(ib_gid_t));
+			ib_member_set_join_state(&item->rec, 0);
+			item->rec.proxy_join = 0;
 		}
-		free(p_rec_item);
-		p_resp_rec++;
 	}
 
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_member_rec_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_mft_record.c b/opensm/opensm/osm_sa_mft_record.c
index 2ad82bd..da786a0 100644
--- a/opensm/opensm/osm_sa_mft_record.c
+++ b/opensm/opensm/osm_sa_mft_record.c
@@ -250,17 +250,8 @@ void osm_mftr_rcv_process(IN void *ctx, IN void *data)
 	osm_madw_t *p_madw = data;
 	const ib_sa_mad_t *p_rcvd_mad;
 	const ib_mft_record_t *p_rcvd_rec;
-	ib_mft_record_t *p_resp_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_mftr_search_ctxt_t context;
-	osm_mftr_item_t *p_rec_item;
 	osm_physp_t *p_req_physp;
 
 	CL_ASSERT(sa);
@@ -311,128 +302,7 @@ void osm_mftr_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4A09: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_mftr_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_mftr_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_mftr_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we limit the number of records to a single packet */
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_mft_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_mft_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4A10: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_mftr_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_mft_record_t));
-
-	p_resp_rec =
-	    (ib_mft_record_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_mftr_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_mft_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_multipath_record.c b/opensm/opensm/osm_sa_multipath_record.c
index e9ddea5..4634ba9 100644
--- a/opensm/opensm/osm_sa_multipath_record.c
+++ b/opensm/opensm/osm_sa_multipath_record.c
@@ -69,10 +69,10 @@
 
 typedef struct _osm_mpr_item {
 	cl_list_item_t list_item;
+	ib_path_rec_t path_rec;
 	const osm_port_t *p_src_port;
 	const osm_port_t *p_dest_port;
 	int hops;
-	ib_path_rec_t path_rec;
 } osm_mpr_item_t;
 
 typedef struct _osm_path_parms {
@@ -1453,102 +1453,12 @@ Exit:
 
 /**********************************************************************
  **********************************************************************/
-static void
-__osm_mpr_rcv_respond(IN osm_sa_t * sa,
-		      IN const osm_madw_t * const p_madw,
-		      IN cl_qlist_t * const p_list)
-{
-	osm_madw_t *p_resp_madw;
-	const ib_sa_mad_t *p_sa_mad;
-	ib_sa_mad_t *p_resp_sa_mad;
-	size_t num_rec;
-	size_t mad_size;
-	ib_path_rec_t *p_resp_pr;
-	ib_multipath_rec_t *p_mpr;
-	osm_mpr_item_t *p_mpr_item;
-	uint32_t i;
-
-	OSM_LOG_ENTER(sa->p_log);
-
-	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	p_mpr = (ib_multipath_rec_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);
-
-	num_rec = cl_qlist_count(p_list);
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-		"Generating response with %zu records\n", num_rec);
-
-	mad_size = IB_SA_MAD_HDR_SIZE + num_rec * sizeof(ib_path_rec_t);
-
-	/*
-	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       mad_size, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR,
-			"ERR 4502: Unable to allocate MAD\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_mpr_item =
-			    (osm_mpr_item_t *) cl_qlist_remove_head(p_list);
-			free(p_mpr_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/*
-	   o15-0.2.7: If MultiPath is supported, then SA shall respond to a
-	   SubnAdmGetMulti() containing a valid MultiPathRecord attribute with
-	   a set of zero or more PathRecords satisfying the constraints indicated
-	   in the MultiPathRecord received. The PathRecord Attribute ID shall be
-	   used in the response.
-	 */
-	p_resp_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD;
-	p_resp_sa_mad->attr_offset = ib_get_attr_offset(sizeof(ib_path_rec_t));
-
-	p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-
-	p_resp_pr = (ib_path_rec_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-	for (i = 0; i < num_rec; i++) {
-		p_mpr_item = (osm_mpr_item_t *) cl_qlist_remove_head(p_list);
-
-		/* Copy the Path Records from the list into the MAD */
-		*p_resp_pr = p_mpr_item->path_rec;
-
-		free(p_mpr_item);
-		p_resp_pr++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(p_list));
-
-	osm_dump_sa_mad(sa->p_log, p_resp_sa_mad, OSM_LOG_FRAMES);
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
-
-Exit:
-	OSM_LOG_EXIT(sa->p_log);
-}
-
-/**********************************************************************
- **********************************************************************/
 void osm_mpr_rcv_process(IN void *context, IN void *data)
 {
 	osm_sa_t *sa = context;
 	osm_madw_t *p_madw = data;
 	const ib_multipath_rec_t *p_mpr;
-	const ib_sa_mad_t *p_sa_mad;
+	ib_sa_mad_t *p_sa_mad;
 	osm_port_t *requester_port;
 	osm_port_t *pp_ports[IB_MULTIPATH_MAX_GIDS];
 	cl_qlist_t pr_list;
@@ -1629,7 +1539,15 @@ void osm_mpr_rcv_process(IN void *context, IN void *data)
 					    p_sa_mad->comp_mask, &pr_list);
 
 	cl_plock_release(sa->p_lock);
-	__osm_mpr_rcv_respond(sa, p_madw, &pr_list);
+
+	/* o15-0.2.7: If MultiPath is supported, then SA shall respond to a
+	   SubnAdmGetMulti() containing a valid MultiPathRecord attribute with
+	   a set of zero or more PathRecords satisfying the constraints
+	   indicated in the MultiPathRecord received. The PathRecord Attribute
+	   ID shall be used in the response.
+	 */
+	p_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD;
+	osm_sa_respond(sa, p_madw, sizeof(ib_path_rec_t), &pr_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_node_record.c b/opensm/opensm/osm_sa_node_record.c
index 58ce2a0..1e9d7dc 100644
--- a/opensm/opensm/osm_sa_node_record.c
+++ b/opensm/opensm/osm_sa_node_record.c
@@ -315,17 +315,8 @@ void osm_nr_rcv_process(IN void *ctx, IN void *data)
 	osm_madw_t *p_madw = data;
 	const ib_sa_mad_t *p_rcvd_mad;
 	const ib_node_record_t *p_rcvd_rec;
-	ib_node_record_t *p_resp_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_nr_search_ctxt_t context;
-	osm_nr_item_t *p_rec_item;
 	osm_physp_t *p_req_physp;
 
 	CL_ASSERT(sa);
@@ -377,117 +368,7 @@ void osm_nr_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1D03: "
-			"Got more than one record for SubnAdmGet (%u)\n",
-			num_rec);
-		osm_sa_send_error(sa, p_madw,
-				  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-		/* need to set the mem free ... */
-		p_rec_item = (osm_nr_item_t *) cl_qlist_remove_head(&rec_list);
-		while (p_rec_item != (osm_nr_item_t *) cl_qlist_end(&rec_list)) {
-			free(p_rec_item);
-			p_rec_item =
-			    (osm_nr_item_t *) cl_qlist_remove_head(&rec_list);
-		}
-
-		goto Exit;
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we limit the number of records to a single packet */
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_node_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_node_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1D06: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_nr_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_node_record_t));
-
-	p_resp_rec =
-	    (ib_node_record_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item = (osm_nr_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_node_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_path_record.c b/opensm/opensm/osm_sa_path_record.c
index 8ed44f4..ef3537b 100644
--- a/opensm/opensm/osm_sa_path_record.c
+++ b/opensm/opensm/osm_sa_path_record.c
@@ -1645,143 +1645,6 @@ Exit:
 
 /**********************************************************************
  **********************************************************************/
-static void
-__osm_pr_rcv_respond(IN osm_sa_t * sa,
-		     IN const osm_madw_t * const p_madw,
-		     IN cl_qlist_t * const p_list)
-{
-	osm_madw_t *p_resp_madw;
-	const ib_sa_mad_t *p_sa_mad;
-	ib_sa_mad_t *p_resp_sa_mad;
-	size_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	size_t trim_num_rec;
-#endif
-	ib_path_rec_t *p_resp_pr;
-	const ib_sa_mad_t *sad_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	osm_pr_item_t *p_pr_item;
-	uint32_t i;
-
-	OSM_LOG_ENTER(sa->p_log);
-
-	num_rec = cl_qlist_count(p_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (sad_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F13: "
-				"Got more than one record for SubnAdmGet (%zu)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-			/* need to set the mem free ... */
-			p_pr_item =
-			    (osm_pr_item_t *) cl_qlist_remove_head(p_list);
-			while (p_pr_item !=
-			       (osm_pr_item_t *) cl_qlist_end(p_list)) {
-				free(p_pr_item);
-				p_pr_item = (osm_pr_item_t *)
-				    cl_qlist_remove_head(p_list);
-			}
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_path_rec_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-		"Generating response with %zu records\n", num_rec);
-
-	if (sad_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_path_rec_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F14: "
-			"Unable to allocate MAD\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_pr_item =
-			    (osm_pr_item_t *) cl_qlist_remove_head(p_list);
-			free(p_pr_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset = ib_get_attr_offset(sizeof(ib_path_rec_t));
-
-	p_resp_pr = (ib_path_rec_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_pr_item = (osm_pr_item_t *) cl_qlist_remove_head(p_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_pr = p_pr_item->path_rec;
-
-		free(p_pr_item);
-		p_resp_pr++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(p_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
-
-Exit:
-	OSM_LOG_EXIT(sa->p_log);
-}
-
-/**********************************************************************
- **********************************************************************/
 void osm_pr_rcv_process(IN void *context, IN void *data)
 {
 	osm_sa_t *sa = context;
@@ -1965,7 +1828,7 @@ Unlock:
 	cl_plock_release(sa->p_lock);
 
 	/* Now, (finally) respond to the PathRecord request */
-	__osm_pr_rcv_respond(sa, p_madw, &pr_list);
+	osm_sa_respond(sa, p_madw, sizeof(ib_path_rec_t), &pr_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_pkey_record.c b/opensm/opensm/osm_sa_pkey_record.c
index 4cf8f9d..5cea525 100644
--- a/opensm/opensm/osm_sa_pkey_record.c
+++ b/opensm/opensm/osm_sa_pkey_record.c
@@ -236,16 +236,7 @@ void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data)
 	const osm_port_t *p_port = NULL;
 	const ib_pkey_table_t *p_pkey;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_pkey_table_record_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_pkey_search_ctxt_t context;
-	osm_pkey_item_t *p_rec_item;
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net64_t comp_mask;
 	osm_physp_t *p_req_physp;
@@ -351,129 +342,7 @@ void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 460A: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_pkey_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_pkey_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_pkey_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_pkey_table_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec *
-				       sizeof(ib_pkey_table_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4606: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_pkey_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_pkey_table_record_t));
-
-	p_resp_rec = (ib_pkey_table_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_pkey_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_pkey_table_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_portinfo_record.c b/opensm/opensm/osm_sa_portinfo_record.c
index 0f7c23d..ad9c9ae 100644
--- a/opensm/opensm/osm_sa_portinfo_record.c
+++ b/opensm/opensm/osm_sa_portinfo_record.c
@@ -479,20 +479,10 @@ void osm_pir_rcv_process(IN void *ctx, IN void *data)
 	const osm_port_t *p_port = NULL;
 	const ib_port_info_t *p_pi;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_portinfo_record_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_pir_search_ctxt_t context;
-	osm_pir_item_t *p_rec_item;
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net64_t comp_mask;
 	osm_physp_t *p_req_physp;
-	boolean_t trusted_req = TRUE;
 
 	CL_ASSERT(sa);
 
@@ -587,115 +577,6 @@ void osm_pir_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2108: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_pir_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_pir_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_pir_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_portinfo_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_portinfo_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2106: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_pir_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_portinfo_record_t));
-
-	p_resp_rec = (ib_portinfo_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
 	/*
 	   p922 - The M_Key returned shall be zero, except in the case of a
 	   trusted request.
@@ -703,24 +584,15 @@ void osm_pir_rcv_process(IN void *ctx, IN void *data)
 	   the mad is valid. Meaning - is either zero or equal to the local
 	   sm_key.
 	 */
-	if (p_rcvd_mad->sm_key == 0)
-		trusted_req = FALSE;
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item = (osm_pir_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec) {
-			*p_resp_rec = p_rec_item->rec;
-			if (trusted_req == FALSE)
-				p_resp_rec->port_info.m_key = 0;
-		}
-		free(p_rec_item);
-		p_resp_rec++;
+	if (!p_rcvd_mad->sm_key) {
+		osm_pir_item_t *item;
+		for (item = (osm_pir_item_t *) cl_qlist_head(&rec_list);
+		     item != (osm_pir_item_t *) cl_qlist_end(&rec_list);
+		     item = (osm_pir_item_t *)cl_qlist_next(&item->list_item))
+			item->rec.port_info.m_key = 0;
 	}
 
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_portinfo_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_service_record.c b/opensm/opensm/osm_sa_service_record.c
index 457934a..ce99db2 100644
--- a/opensm/opensm/osm_sa_service_record.c
+++ b/opensm/opensm/osm_sa_service_record.c
@@ -211,158 +211,25 @@ Exit:
  **********************************************************************/
 static void
 __osm_sr_rcv_respond(IN osm_sa_t * sa,
-		     IN const osm_madw_t * const p_madw,
+		     IN osm_madw_t * const p_madw,
 		     IN cl_qlist_t * const p_list)
 {
-	osm_madw_t *p_resp_madw;
-	const ib_sa_mad_t *p_sa_mad;
-	ib_sa_mad_t *p_resp_sa_mad;
-	uint32_t num_rec, num_copied;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	ib_service_record_t *p_resp_sr;
-	osm_sr_item_t *p_sr_item;
-	const ib_sa_mad_t *p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	boolean_t trusted_req = TRUE;
-
-	OSM_LOG_ENTER(sa->p_log);
-
-	num_rec = cl_qlist_count(p_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2406: "
-			"Got more than one record for SubnAdmGet (%u).\n",
-			num_rec);
-		osm_sa_send_error(sa, p_madw,
-				  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-		/* need to set the mem free ... */
-		p_sr_item = (osm_sr_item_t *) cl_qlist_remove_head(p_list);
-		while (p_sr_item != (osm_sr_item_t *) cl_qlist_end(p_list)) {
-			free(p_sr_item);
-			p_sr_item =
-			    (osm_sr_item_t *) cl_qlist_remove_head(p_list);
-		}
-
-		goto Exit;
-	}
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_service_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG)) {
-		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-			"Generating response with %u records\n", num_rec);
-	}
-
-	/*
-	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
+	/* p923 - The ServiceKey shall be set to 0, except in the case of
+	   a trusted request.
+	   Note: In the mad controller we check that the SM_Key received on
+	   the mad is valid. Meaning - is either zero or equal to the local
+	   sm_key.
 	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_service_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2402: "
-			"Unable to allocate MAD\n");
-		/* Release the quick pool items */
-		p_sr_item = (osm_sr_item_t *) cl_qlist_remove_head(p_list);
-		while (p_sr_item != (osm_sr_item_t *) cl_qlist_end(p_list)) {
-			free(p_sr_item);
-			p_sr_item =
-			    (osm_sr_item_t *) cl_qlist_remove_head(p_list);
-		}
-
-		goto Exit;
+	if (!osm_madw_get_sa_mad_ptr(p_madw)->sm_key) {
+		osm_sr_item_t *item;
+		for (item = (osm_sr_item_t *) cl_qlist_head(p_list);
+		     item != (osm_sr_item_t *) cl_qlist_end(p_list);
+		     item = (osm_sr_item_t *)cl_qlist_next(&item->list_item))
+			memset(item->service_rec.service_key, 0,
+			       sizeof(item->service_rec.service_key));
 	}
 
-	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
-
-	/* but what if it was a SET ? setting the response bit is not enough */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_SET)
-		p_resp_sa_mad->method = IB_MAD_METHOD_GET;
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_service_record_t));
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	p_resp_sr =
-	    (ib_service_record_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-	if (p_resp_sa_mad->method != IB_MAD_METHOD_GETTABLE_RESP &&
-	    num_rec == 0) {
-		p_resp_sa_mad->status = IB_SA_MAD_STATUS_NO_RECORDS;
-		memset(p_resp_sr, 0, sizeof(*p_resp_sr));
-	} else {
-		/*
-		   p923 - The ServiceKey shall be set to 0, except in the case of a trusted
-		   request.
-		   Note: In the mad controller we check that the SM_Key received on
-		   the mad is valid. Meaning - is either zero or equal to the local
-		   sm_key.
-		 */
-		if (p_sa_mad->sm_key == 0)
-			trusted_req = FALSE;
-
-		p_sr_item = (osm_sr_item_t *) cl_qlist_remove_head(p_list);
-
-		/* we need to track the number of copied items so we can
-		 * stop the copy - but clear them all
-		 */
-		num_copied = 0;
-		while (p_sr_item != (osm_sr_item_t *) cl_qlist_end(p_list)) {
-			/*  Copy the Link Records from the list into the MAD */
-			if (num_copied < num_rec) {
-				*p_resp_sr = p_sr_item->service_rec;
-				if (trusted_req == FALSE)
-					memset(p_resp_sr->service_key, 0,
-					       sizeof(p_resp_sr->service_key));
-
-				num_copied++;
-			}
-			free(p_sr_item);
-			p_resp_sr++;
-			p_sr_item =
-			    (osm_sr_item_t *) cl_qlist_remove_head(p_list);
-		}
-	}
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
-
-Exit:
-	OSM_LOG_EXIT(sa->p_log);
+	osm_sa_respond(sa, p_madw, sizeof(ib_service_record_t), p_list);
 }
 
 /**********************************************************************
@@ -598,7 +465,7 @@ Exit:
  **********************************************************************/
 static void
 osm_sr_rcv_process_get_method(IN osm_sa_t * sa,
-			      IN const osm_madw_t * const p_madw)
+			      IN osm_madw_t * const p_madw)
 {
 	ib_sa_mad_t *p_sa_mad;
 	ib_service_record_t *p_recvd_service_rec;
@@ -666,7 +533,7 @@ Exit:
  **********************************************************************/
 static void
 osm_sr_rcv_process_set_method(IN osm_sa_t * sa,
-			      IN const osm_madw_t * const p_madw)
+			      IN osm_madw_t * const p_madw)
 {
 	ib_sa_mad_t *p_sa_mad;
 	ib_service_record_t *p_recvd_service_rec;
@@ -776,7 +643,7 @@ Exit:
  **********************************************************************/
 static void
 osm_sr_rcv_process_delete_method(IN osm_sa_t * sa,
-				 IN const osm_madw_t * const p_madw)
+				 IN osm_madw_t * const p_madw)
 {
 	ib_sa_mad_t *p_sa_mad;
 	ib_service_record_t *p_recvd_service_rec;
diff --git a/opensm/opensm/osm_sa_slvl_record.c b/opensm/opensm/osm_sa_slvl_record.c
index c56f7eb..ae72623 100644
--- a/opensm/opensm/osm_sa_slvl_record.c
+++ b/opensm/opensm/osm_sa_slvl_record.c
@@ -227,16 +227,7 @@ void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data)
 	const cl_ptr_vector_t *p_tbl;
 	const osm_port_t *p_port = NULL;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_slvl_table_record_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_slvl_search_ctxt_t context;
-	osm_slvl_item_t *p_rec_item;
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net64_t comp_mask;
 	osm_physp_t *p_req_physp;
@@ -328,129 +319,7 @@ void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2607: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_slvl_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_slvl_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_slvl_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_slvl_table_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (p_rcvd_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec *
-				       sizeof(ib_slvl_table_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2605: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_slvl_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_slvl_table_record_t));
-
-	p_resp_rec = (ib_slvl_table_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_slvl_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_slvl_table_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_sminfo_record.c b/opensm/opensm/osm_sa_sminfo_record.c
index 77eee45..75c50ad 100644
--- a/opensm/opensm/osm_sa_sminfo_record.c
+++ b/opensm/opensm/osm_sa_sminfo_record.c
@@ -187,16 +187,7 @@ void osm_smir_rcv_process(IN void *ctx, IN void *data)
 	const osm_port_t *p_port = NULL;
 	const ib_sm_info_t *p_smi;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_sminfo_record_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_smir_search_ctxt_t context;
-	osm_smir_item_t *p_rec_item;
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net64_t comp_mask;
 	ib_net64_t port_guid;
@@ -341,129 +332,7 @@ void osm_smir_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (sad_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2808: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item =
-			    (osm_smir_item_t *) cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_smir_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_smir_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_sminfo_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (sad_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec * sizeof(ib_sminfo_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2807: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_smir_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, sad_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_sminfo_record_t));
-
-	p_resp_rec = (ib_sminfo_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_smir_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec) {
-			*p_resp_rec = p_rec_item->rec;
-			p_resp_rec->sm_info.sm_key = 0;
-		}
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_sminfo_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_sw_info_record.c b/opensm/opensm/osm_sa_sw_info_record.c
index c2cb740..bae4c75 100644
--- a/opensm/opensm/osm_sa_sw_info_record.c
+++ b/opensm/opensm/osm_sa_sw_info_record.c
@@ -245,17 +245,8 @@ void osm_sir_rcv_process(IN void *ctx, IN void *data)
 	osm_madw_t *p_madw = data;
 	const ib_sa_mad_t *sad_mad;
 	const ib_switch_info_record_t *p_rcvd_rec;
-	ib_switch_info_record_t *p_resp_rec;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_sir_search_ctxt_t context;
-	osm_sir_item_t *p_rec_item;
 	osm_physp_t *p_req_physp;
 
 	CL_ASSERT(sa);
@@ -310,119 +301,7 @@ void osm_sir_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (sad_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5303: "
-			"Got more than one record for SubnAdmGet (%u)\n",
-			num_rec);
-		osm_sa_send_error(sa, p_madw,
-				  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-		/* need to set the mem free ... */
-		p_rec_item = (osm_sir_item_t *) cl_qlist_remove_head(&rec_list);
-		while (p_rec_item != (osm_sir_item_t *) cl_qlist_end(&rec_list)) {
-			free(p_rec_item);
-			p_rec_item =
-			    (osm_sir_item_t *) cl_qlist_remove_head(&rec_list);
-		}
-
-		goto Exit;
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we limit the number of records to a single packet */
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_switch_info_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (sad_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec *
-				       sizeof(ib_switch_info_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5306: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item =
-			    (osm_sir_item_t *) cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, sad_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_switch_info_record_t));
-
-	p_resp_rec = (ib_switch_info_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item = (osm_sir_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_switch_info_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_sa_vlarb_record.c b/opensm/opensm/osm_sa_vlarb_record.c
index a06f8e9..5948cc1 100644
--- a/opensm/opensm/osm_sa_vlarb_record.c
+++ b/opensm/opensm/osm_sa_vlarb_record.c
@@ -242,16 +242,7 @@ void osm_vlarb_rec_rcv_process(IN void *ctx, IN void *data)
 	const osm_port_t *p_port = NULL;
 	const ib_vl_arb_table_t *p_vl_arb;
 	cl_qlist_t rec_list;
-	osm_madw_t *p_resp_madw;
-	ib_sa_mad_t *p_resp_sa_mad;
-	ib_vl_arb_table_record_t *p_resp_rec;
-	uint32_t num_rec, pre_trim_num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	uint32_t trim_num_rec;
-#endif
-	uint32_t i;
 	osm_vl_arb_search_ctxt_t context;
-	osm_vl_arb_item_t *p_rec_item;
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net64_t comp_mask;
 	osm_physp_t *p_req_physp;
@@ -344,129 +335,7 @@ void osm_vlarb_rec_rcv_process(IN void *ctx, IN void *data)
 
 	cl_plock_release(sa->p_lock);
 
-	num_rec = cl_qlist_count(&rec_list);
-
-	/*
-	 * C15-0.1.30:
-	 * If we do a SubnAdmGet and got more than one record it is an error !
-	 */
-	if (sad_mad->method == IB_MAD_METHOD_GET) {
-		if (num_rec == 0) {
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_NO_RECORDS);
-			goto Exit;
-		}
-		if (num_rec > 1) {
-			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2A08: "
-				"Got more than one record for SubnAdmGet (%u)\n",
-				num_rec);
-			osm_sa_send_error(sa, p_madw,
-					  IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-			/* need to set the mem free ... */
-			p_rec_item = (osm_vl_arb_item_t *)
-			    cl_qlist_remove_head(&rec_list);
-			while (p_rec_item !=
-			       (osm_vl_arb_item_t *) cl_qlist_end(&rec_list)) {
-				free(p_rec_item);
-				p_rec_item = (osm_vl_arb_item_t *)
-				    cl_qlist_remove_head(&rec_list);
-			}
-
-			goto Exit;
-		}
-	}
-
-	pre_trim_num_rec = num_rec;
-#ifndef VENDOR_RMPP_SUPPORT
-	trim_num_rec =
-	    (MAD_BLOCK_SIZE -
-	     IB_SA_MAD_HDR_SIZE) / sizeof(ib_vl_arb_table_record_t);
-	if (trim_num_rec < num_rec) {
-		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
-			"Number of records:%u trimmed to:%u to fit in one MAD\n",
-			num_rec, trim_num_rec);
-		num_rec = trim_num_rec;
-	}
-#endif
-
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
-
-	if (sad_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
-		goto Exit;
-	}
-
-	/*
-	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
-	 */
-	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
-				       num_rec *
-				       sizeof(ib_vl_arb_table_record_t) +
-				       IB_SA_MAD_HDR_SIZE, &p_madw->mad_addr);
-
-	if (!p_resp_madw) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2A06: "
-			"osm_mad_pool_get failed\n");
-
-		for (i = 0; i < num_rec; i++) {
-			p_rec_item = (osm_vl_arb_item_t *)
-			    cl_qlist_remove_head(&rec_list);
-			free(p_rec_item);
-		}
-
-		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
-		goto Exit;
-	}
-
-	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
-
-	/*
-	   Copy the MAD header back into the response mad.
-	   Set the 'R' bit and the payload length,
-	   Then copy all records from the list into the response payload.
-	 */
-
-	memcpy(p_resp_sa_mad, sad_mad, IB_SA_MAD_HDR_SIZE);
-	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
-	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
-	p_resp_sa_mad->sm_key = 0;
-
-	/* Fill in the offset (paylen will be done by the rmpp SAR) */
-	p_resp_sa_mad->attr_offset =
-	    ib_get_attr_offset(sizeof(ib_vl_arb_table_record_t));
-
-	p_resp_rec = (ib_vl_arb_table_record_t *)
-	    ib_sa_mad_get_payload_ptr(p_resp_sa_mad);
-
-#ifndef VENDOR_RMPP_SUPPORT
-	/* we support only one packet RMPP - so we will set the first and
-	   last flags for gettable */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
-		p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
-		p_resp_sa_mad->rmpp_flags =
-		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
-		    IB_RMPP_FLAG_ACTIVE;
-	}
-#else
-	/* forcefully define the packet as RMPP one */
-	if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
-		p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
-#endif
-
-	for (i = 0; i < pre_trim_num_rec; i++) {
-		p_rec_item =
-		    (osm_vl_arb_item_t *) cl_qlist_remove_head(&rec_list);
-		/* copy only if not trimmed */
-		if (i < num_rec)
-			*p_resp_rec = p_rec_item->rec;
-		free(p_rec_item);
-		p_resp_rec++;
-	}
-
-	CL_ASSERT(cl_is_qlist_empty(&rec_list));
-
-	osm_sa_vendor_send(p_resp_madw->h_bind, p_resp_madw, FALSE, sa->p_subn);
+	osm_sa_respond(sa, p_madw, sizeof(ib_vl_arb_table_record_t), &rec_list);
 
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
-- 
1.5.4.rc2.60.gb2e62




More information about the general mailing list