[openib-general] [PATCH v3] sa_query: Add service record support

Hal Rosenstock halr at voltaire.com
Tue Jul 5 13:19:32 PDT 2005


sa_query: Add service record support

Signed-off-by: Hal Rosenstock <halr at voltaire.com>

Index: include/ib_sa.h
===================================================================
--- include/ib_sa.h	(revision 2771)
+++ include/ib_sa.h	(working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -193,6 +194,61 @@
 	int          proxy_join;
 };
 
+/* Service Record Component Mask Sec 15.2.5.14 Ver 1.1	*/
+#define IB_SR_COMPMASK_SID				IB_SA_COMP_MASK(0)
+#define IB_SR_COMPMASK_SGID				IB_SA_COMP_MASK(1)
+#define IB_SR_COMPMASK_SPKEY				IB_SA_COMP_MASK(2)
+#define IB_SR_COMPMASK_RES1				IB_SA_COMP_MASK(3)
+#define IB_SR_COMPMASK_SLEASE				IB_SA_COMP_MASK(4)
+#define IB_SR_COMPMASK_SKEY				IB_SA_COMP_MASK(5)
+#define IB_SR_COMPMASK_SNAME				IB_SA_COMP_MASK(6)
+#define IB_SR_COMPMASK_SDATA8_0				IB_SA_COMP_MASK(7)
+#define IB_SR_COMPMASK_SDATA8_1				IB_SA_COMP_MASK(8)
+#define IB_SR_COMPMASK_SDATA8_2				IB_SA_COMP_MASK(9)
+#define IB_SR_COMPMASK_SDATA8_3				IB_SA_COMP_MASK(10)
+#define IB_SR_COMPMASK_SDATA8_4				IB_SA_COMP_MASK(11)
+#define IB_SR_COMPMASK_SDATA8_5				IB_SA_COMP_MASK(12)
+#define IB_SR_COMPMASK_SDATA8_6				IB_SA_COMP_MASK(13)
+#define IB_SR_COMPMASK_SDATA8_7				IB_SA_COMP_MASK(14)
+#define IB_SR_COMPMASK_SDATA8_8				IB_SA_COMP_MASK(15)
+#define IB_SR_COMPMASK_SDATA8_9				IB_SA_COMP_MASK(16)
+#define IB_SR_COMPMASK_SDATA8_10			IB_SA_COMP_MASK(17)
+#define IB_SR_COMPMASK_SDATA8_11			IB_SA_COMP_MASK(18)
+#define IB_SR_COMPMASK_SDATA8_12			IB_SA_COMP_MASK(19)
+#define IB_SR_COMPMASK_SDATA8_13			IB_SA_COMP_MASK(20)
+#define IB_SR_COMPMASK_SDATA8_14			IB_SA_COMP_MASK(21)
+#define IB_SR_COMPMASK_SDATA8_15			IB_SA_COMP_MASK(22)
+#define IB_SR_COMPMASK_SDATA16_0			IB_SA_COMP_MASK(23)
+#define IB_SR_COMPMASK_SDATA16_1			IB_SA_COMP_MASK(24)
+#define IB_SR_COMPMASK_SDATA16_2			IB_SA_COMP_MASK(25)
+#define IB_SR_COMPMASK_SDATA16_3			IB_SA_COMP_MASK(26)
+#define IB_SR_COMPMASK_SDATA16_4			IB_SA_COMP_MASK(27)
+#define IB_SR_COMPMASK_SDATA16_5			IB_SA_COMP_MASK(28)
+#define IB_SR_COMPMASK_SDATA16_6			IB_SA_COMP_MASK(29)
+#define IB_SR_COMPMASK_SDATA16_7			IB_SA_COMP_MASK(30)
+#define IB_SR_COMPMASK_SDATA32_0			IB_SA_COMP_MASK(31)
+#define IB_SR_COMPMASK_SDATA32_1			IB_SA_COMP_MASK(32)
+#define IB_SR_COMPMASK_SDATA32_2			IB_SA_COMP_MASK(33)
+#define IB_SR_COMPMASK_SDATA32_3			IB_SA_COMP_MASK(34)
+#define IB_SR_COMPMASK_SDATA64_0			IB_SA_COMP_MASK(35)
+#define IB_SR_COMPMASK_SDATA64_1			IB_SA_COMP_MASK(36)
+
+#define IB_DEFAULT_SERVICE_LEASE 	0xFFFFFFFF
+
+struct ib_sa_service_rec {
+	u64		id;
+	union ib_gid	gid;		
+	u16 		pkey;
+	/* reserved */
+	u32		lease;
+	u8		key[16];
+	u8		name[64];
+	u8		data8[16];
+	u16		data16[8];
+	u32		data32[4];
+	u64		data64[2];
+};
+
 struct ib_sa_query;
 
 void ib_sa_cancel_query(int id, struct ib_sa_query *query);
@@ -218,6 +274,17 @@
 			     void *context,
 			     struct ib_sa_query **query);
 
+int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
+			 u8 method,
+			 struct ib_sa_service_rec *rec,
+			 ib_sa_comp_mask comp_mask,
+			 int timeout_ms, int gfp_mask,
+			 void (*callback)(int status,
+					  struct ib_sa_service_rec *resp,
+					  void *context),
+			 void *context,
+			 struct ib_sa_query **sa_query);
+
 /**
  * ib_sa_mcmember_rec_set - Start an MCMember set query
  * @device:device to send query on
Index: core/sa_query.c
===================================================================
--- core/sa_query.c	(revision 2771)
+++ core/sa_query.c	(working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -79,6 +80,12 @@
 	int                 id;
 };
 
+struct ib_sa_service_query {
+	void (*callback)(int, struct ib_sa_service_rec *, void *);
+	void *context;
+	struct ib_sa_query sa_query;
+};
+
 struct ib_sa_path_query {
 	void (*callback)(int, struct ib_sa_path_rec *, void *);
 	void *context;
@@ -320,6 +327,54 @@
 	  .size_bits    = 23 },
 };
 
+#define SERVICE_REC_FIELD(field) \
+	.struct_offset_bytes = offsetof(struct ib_sa_service_rec, field),	\
+	.struct_size_bytes   = sizeof ((struct ib_sa_service_rec *) 0)->field,	\
+	.field_name          = "sa_service_rec:" #field
+
+static const struct ib_field service_rec_table[] = {
+	{ SERVICE_REC_FIELD(id),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 64 },
+	{ SERVICE_REC_FIELD(gid),
+	  .offset_words = 2,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ SERVICE_REC_FIELD(pkey),
+	  .offset_words = 6,
+	  .offset_bits  = 0,
+	  .size_bits    = 16 },
+	{ SERVICE_REC_FIELD(lease),
+	  .offset_words = 7,
+	  .offset_bits  = 0,
+	  .size_bits    = 32 },
+	{ SERVICE_REC_FIELD(key),
+	  .offset_words = 8,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ SERVICE_REC_FIELD(name),
+	  .offset_words = 12,
+	  .offset_bits  = 0,
+	  .size_bits    = 64*8 },
+	{ SERVICE_REC_FIELD(data8),
+	  .offset_words = 28,
+	  .offset_bits  = 0,
+	  .size_bits    = 16*8 },
+	{ SERVICE_REC_FIELD(data16),
+	  .offset_words = 32,
+	  .offset_bits  = 0,
+	  .size_bits    = 8*16 },
+	{ SERVICE_REC_FIELD(data32),
+	  .offset_words = 36,
+	  .offset_bits  = 0,
+	  .size_bits    = 4*32 },
+	{ SERVICE_REC_FIELD(data64),
+	  .offset_words = 40,
+	  .offset_bits  = 0,
+	  .size_bits    = 2*64 },
+};
+
 static void free_sm_ah(struct kref *kref)
 {
 	struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
@@ -443,7 +498,6 @@
 				 .remote_qpn  = 1,
 				 .remote_qkey = IB_QP1_QKEY,
 				 .timeout_ms  = timeout_ms,
-				 .retries     = 0 
 			 }
 		 }
 	};
@@ -596,6 +650,114 @@
 }
 EXPORT_SYMBOL(ib_sa_path_rec_get);
 
+static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
+				    int status,
+				    struct ib_sa_mad *mad)
+{
+	struct ib_sa_service_query *query =
+		container_of(sa_query, struct ib_sa_service_query, sa_query);
+
+	if (mad) {
+		struct ib_sa_service_rec rec;
+
+		ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
+			  mad->data, &rec);
+		query->callback(status, &rec, query->context);
+	} else
+		query->callback(status, NULL, query->context);
+}
+
+static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
+{
+	kfree(sa_query->mad);
+	kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
+}
+
+/**
+ * ib_sa_service_rec_query - Start Service Record operation
+ * @device:device to send request on
+ * @port_num: port number to send request on
+ * @method:SA method - should be get, set, or delete
+ * @rec:Service Record to send in request
+ * @comp_mask:component mask to send in request
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when request completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:request context, used to cancel request
+ *
+ * Send a Service Record set/get/delete to the SA to register,
+ * unregister or query a service record.
+ * The callback function will be called when the request completes (or
+ * fails); status is 0 for a successful response, -EINTR if the query
+ * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
+ * occurred sending the query.  The resp parameter of the callback is
+ * only valid if status is 0.
+ *
+ * If the return value of ib_sa_service_rec_query() is negative, it is an
+ * error code.  Otherwise it is a request ID that can be used to cancel
+ * the query.
+ */
+int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
+			    struct ib_sa_service_rec *rec,
+			    ib_sa_comp_mask comp_mask,
+			    int timeout_ms, int gfp_mask,
+			    void (*callback)(int status,
+					     struct ib_sa_service_rec *resp,
+					     void *context),
+			    void *context,
+			    struct ib_sa_query **sa_query)
+{
+	struct ib_sa_service_query *query;
+	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
+	struct ib_mad_agent *agent  = port->agent;
+	int ret;
+
+	if (method != IB_MGMT_METHOD_GET &&
+	    method != IB_MGMT_METHOD_SET &&
+	    method != IB_SA_METHOD_DELETE)
+		return -EINVAL;
+
+	query = kmalloc(sizeof *query, gfp_mask);
+	if (!query)
+		return -ENOMEM;
+	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
+	if (!query->sa_query.mad) {
+		kfree(query);
+		return -ENOMEM;
+	}
+
+	query->callback = callback;
+	query->context  = context;
+
+	init_mad(query->sa_query.mad, agent);
+
+	query->sa_query.callback              = callback ? ib_sa_service_rec_callback : NULL;
+	query->sa_query.release               = ib_sa_service_rec_release;
+	query->sa_query.port                  = port;
+	query->sa_query.mad->mad_hdr.method   = method;
+	query->sa_query.mad->mad_hdr.attr_id  =
+				cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
+	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+
+	ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
+		rec, query->sa_query.mad->data);
+
+	*sa_query = &query->sa_query;
+
+	ret = send_mad(&query->sa_query, timeout_ms);
+	if (ret < 0) {
+		*sa_query = NULL;
+		kfree(query->sa_query.mad);
+		kfree(query);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_sa_service_rec_query);
+
 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
 					int status,
 					struct ib_sa_mad *mad)






More information about the general mailing list