Skip to content

Commit cbae32c

Browse files
Hal RosenstockLinus Torvalds
authored andcommitted
[PATCH] IB: Add Service Record support to SA client
Add Service Record support to SA client Signed-off-by: Hal Rosenstock <[email protected]> Cc: Roland Dreier <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent fa619a7 commit cbae32c

File tree

2 files changed

+236
-5
lines changed

2 files changed

+236
-5
lines changed

drivers/infiniband/core/sa_query.c

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2004 Topspin Communications. All rights reserved.
3+
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
34
*
45
* This software is available to you under a choice of one of two
56
* licenses. You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
2930
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3031
* SOFTWARE.
3132
*
32-
* $Id: sa_query.c 1389 2004-12-27 22:56:47Z roland $
33+
* $Id: sa_query.c 2811 2005-07-06 18:11:43Z halr $
3334
*/
3435

3536
#include <linux/module.h>
@@ -79,6 +80,12 @@ struct ib_sa_query {
7980
int id;
8081
};
8182

83+
struct ib_sa_service_query {
84+
void (*callback)(int, struct ib_sa_service_rec *, void *);
85+
void *context;
86+
struct ib_sa_query sa_query;
87+
};
88+
8289
struct ib_sa_path_query {
8390
void (*callback)(int, struct ib_sa_path_rec *, void *);
8491
void *context;
@@ -320,6 +327,54 @@ static const struct ib_field mcmember_rec_table[] = {
320327
.size_bits = 23 },
321328
};
322329

330+
#define SERVICE_REC_FIELD(field) \
331+
.struct_offset_bytes = offsetof(struct ib_sa_service_rec, field), \
332+
.struct_size_bytes = sizeof ((struct ib_sa_service_rec *) 0)->field, \
333+
.field_name = "sa_service_rec:" #field
334+
335+
static const struct ib_field service_rec_table[] = {
336+
{ SERVICE_REC_FIELD(id),
337+
.offset_words = 0,
338+
.offset_bits = 0,
339+
.size_bits = 64 },
340+
{ SERVICE_REC_FIELD(gid),
341+
.offset_words = 2,
342+
.offset_bits = 0,
343+
.size_bits = 128 },
344+
{ SERVICE_REC_FIELD(pkey),
345+
.offset_words = 6,
346+
.offset_bits = 0,
347+
.size_bits = 16 },
348+
{ SERVICE_REC_FIELD(lease),
349+
.offset_words = 7,
350+
.offset_bits = 0,
351+
.size_bits = 32 },
352+
{ SERVICE_REC_FIELD(key),
353+
.offset_words = 8,
354+
.offset_bits = 0,
355+
.size_bits = 128 },
356+
{ SERVICE_REC_FIELD(name),
357+
.offset_words = 12,
358+
.offset_bits = 0,
359+
.size_bits = 64*8 },
360+
{ SERVICE_REC_FIELD(data8),
361+
.offset_words = 28,
362+
.offset_bits = 0,
363+
.size_bits = 16*8 },
364+
{ SERVICE_REC_FIELD(data16),
365+
.offset_words = 32,
366+
.offset_bits = 0,
367+
.size_bits = 8*16 },
368+
{ SERVICE_REC_FIELD(data32),
369+
.offset_words = 36,
370+
.offset_bits = 0,
371+
.size_bits = 4*32 },
372+
{ SERVICE_REC_FIELD(data64),
373+
.offset_words = 40,
374+
.offset_bits = 0,
375+
.size_bits = 2*64 },
376+
};
377+
323378
static void free_sm_ah(struct kref *kref)
324379
{
325380
struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
@@ -443,7 +498,6 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms)
443498
.remote_qpn = 1,
444499
.remote_qkey = IB_QP1_QKEY,
445500
.timeout_ms = timeout_ms,
446-
.retries = 0
447501
}
448502
}
449503
};
@@ -596,6 +650,114 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
596650
}
597651
EXPORT_SYMBOL(ib_sa_path_rec_get);
598652

653+
static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
654+
int status,
655+
struct ib_sa_mad *mad)
656+
{
657+
struct ib_sa_service_query *query =
658+
container_of(sa_query, struct ib_sa_service_query, sa_query);
659+
660+
if (mad) {
661+
struct ib_sa_service_rec rec;
662+
663+
ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
664+
mad->data, &rec);
665+
query->callback(status, &rec, query->context);
666+
} else
667+
query->callback(status, NULL, query->context);
668+
}
669+
670+
static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
671+
{
672+
kfree(sa_query->mad);
673+
kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
674+
}
675+
676+
/**
677+
* ib_sa_service_rec_query - Start Service Record operation
678+
* @device:device to send request on
679+
* @port_num: port number to send request on
680+
* @method:SA method - should be get, set, or delete
681+
* @rec:Service Record to send in request
682+
* @comp_mask:component mask to send in request
683+
* @timeout_ms:time to wait for response
684+
* @gfp_mask:GFP mask to use for internal allocations
685+
* @callback:function called when request completes, times out or is
686+
* canceled
687+
* @context:opaque user context passed to callback
688+
* @sa_query:request context, used to cancel request
689+
*
690+
* Send a Service Record set/get/delete to the SA to register,
691+
* unregister or query a service record.
692+
* The callback function will be called when the request completes (or
693+
* fails); status is 0 for a successful response, -EINTR if the query
694+
* is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
695+
* occurred sending the query. The resp parameter of the callback is
696+
* only valid if status is 0.
697+
*
698+
* If the return value of ib_sa_service_rec_query() is negative, it is an
699+
* error code. Otherwise it is a request ID that can be used to cancel
700+
* the query.
701+
*/
702+
int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
703+
struct ib_sa_service_rec *rec,
704+
ib_sa_comp_mask comp_mask,
705+
int timeout_ms, int gfp_mask,
706+
void (*callback)(int status,
707+
struct ib_sa_service_rec *resp,
708+
void *context),
709+
void *context,
710+
struct ib_sa_query **sa_query)
711+
{
712+
struct ib_sa_service_query *query;
713+
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
714+
struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port];
715+
struct ib_mad_agent *agent = port->agent;
716+
int ret;
717+
718+
if (method != IB_MGMT_METHOD_GET &&
719+
method != IB_MGMT_METHOD_SET &&
720+
method != IB_SA_METHOD_DELETE)
721+
return -EINVAL;
722+
723+
query = kmalloc(sizeof *query, gfp_mask);
724+
if (!query)
725+
return -ENOMEM;
726+
query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
727+
if (!query->sa_query.mad) {
728+
kfree(query);
729+
return -ENOMEM;
730+
}
731+
732+
query->callback = callback;
733+
query->context = context;
734+
735+
init_mad(query->sa_query.mad, agent);
736+
737+
query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
738+
query->sa_query.release = ib_sa_service_rec_release;
739+
query->sa_query.port = port;
740+
query->sa_query.mad->mad_hdr.method = method;
741+
query->sa_query.mad->mad_hdr.attr_id =
742+
cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
743+
query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
744+
745+
ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
746+
rec, query->sa_query.mad->data);
747+
748+
*sa_query = &query->sa_query;
749+
750+
ret = send_mad(&query->sa_query, timeout_ms);
751+
if (ret < 0) {
752+
*sa_query = NULL;
753+
kfree(query->sa_query.mad);
754+
kfree(query);
755+
}
756+
757+
return ret;
758+
}
759+
EXPORT_SYMBOL(ib_sa_service_rec_query);
760+
599761
static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
600762
int status,
601763
struct ib_sa_mad *mad)

drivers/infiniband/include/ib_sa.h

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2004 Topspin Communications. All rights reserved.
3+
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
34
*
45
* This software is available to you under a choice of one of two
56
* licenses. You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
2930
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3031
* SOFTWARE.
3132
*
32-
* $Id: ib_sa.h 1389 2004-12-27 22:56:47Z roland $
33+
* $Id: ib_sa.h 2811 2005-07-06 18:11:43Z halr $
3334
*/
3435

3536
#ifndef IB_SA_H
@@ -41,9 +42,11 @@
4142
#include <ib_mad.h>
4243

4344
enum {
44-
IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */
45+
IB_SA_CLASS_VERSION = 2, /* IB spec version 1.1/1.2 */
4546

46-
IB_SA_METHOD_DELETE = 0x15
47+
IB_SA_METHOD_GET_TABLE = 0x12,
48+
IB_SA_METHOD_GET_TABLE_RESP = 0x92,
49+
IB_SA_METHOD_DELETE = 0x15
4750
};
4851

4952
enum ib_sa_selector {
@@ -191,6 +194,61 @@ struct ib_sa_mcmember_rec {
191194
int proxy_join;
192195
};
193196

197+
/* Service Record Component Mask Sec 15.2.5.14 Ver 1.1 */
198+
#define IB_SA_SERVICE_REC_SERVICE_ID IB_SA_COMP_MASK( 0)
199+
#define IB_SA_SERVICE_REC_SERVICE_GID IB_SA_COMP_MASK( 1)
200+
#define IB_SA_SERVICE_REC_SERVICE_PKEY IB_SA_COMP_MASK( 2)
201+
/* reserved: 3 */
202+
#define IB_SA_SERVICE_REC_SERVICE_LEASE IB_SA_COMP_MASK( 4)
203+
#define IB_SA_SERVICE_REC_SERVICE_KEY IB_SA_COMP_MASK( 5)
204+
#define IB_SA_SERVICE_REC_SERVICE_NAME IB_SA_COMP_MASK( 6)
205+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_0 IB_SA_COMP_MASK( 7)
206+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_1 IB_SA_COMP_MASK( 8)
207+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_2 IB_SA_COMP_MASK( 9)
208+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_3 IB_SA_COMP_MASK(10)
209+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_4 IB_SA_COMP_MASK(11)
210+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_5 IB_SA_COMP_MASK(12)
211+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_6 IB_SA_COMP_MASK(13)
212+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_7 IB_SA_COMP_MASK(14)
213+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_8 IB_SA_COMP_MASK(15)
214+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_9 IB_SA_COMP_MASK(16)
215+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_10 IB_SA_COMP_MASK(17)
216+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_11 IB_SA_COMP_MASK(18)
217+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_12 IB_SA_COMP_MASK(19)
218+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_13 IB_SA_COMP_MASK(20)
219+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_14 IB_SA_COMP_MASK(21)
220+
#define IB_SA_SERVICE_REC_SERVICE_DATA8_15 IB_SA_COMP_MASK(22)
221+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_0 IB_SA_COMP_MASK(23)
222+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_1 IB_SA_COMP_MASK(24)
223+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_2 IB_SA_COMP_MASK(25)
224+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_3 IB_SA_COMP_MASK(26)
225+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_4 IB_SA_COMP_MASK(27)
226+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_5 IB_SA_COMP_MASK(28)
227+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_6 IB_SA_COMP_MASK(29)
228+
#define IB_SA_SERVICE_REC_SERVICE_DATA16_7 IB_SA_COMP_MASK(30)
229+
#define IB_SA_SERVICE_REC_SERVICE_DATA32_0 IB_SA_COMP_MASK(31)
230+
#define IB_SA_SERVICE_REC_SERVICE_DATA32_1 IB_SA_COMP_MASK(32)
231+
#define IB_SA_SERVICE_REC_SERVICE_DATA32_2 IB_SA_COMP_MASK(33)
232+
#define IB_SA_SERVICE_REC_SERVICE_DATA32_3 IB_SA_COMP_MASK(34)
233+
#define IB_SA_SERVICE_REC_SERVICE_DATA64_0 IB_SA_COMP_MASK(35)
234+
#define IB_SA_SERVICE_REC_SERVICE_DATA64_1 IB_SA_COMP_MASK(36)
235+
236+
#define IB_DEFAULT_SERVICE_LEASE 0xFFFFFFFF
237+
238+
struct ib_sa_service_rec {
239+
u64 id;
240+
union ib_gid gid;
241+
u16 pkey;
242+
/* reserved */
243+
u32 lease;
244+
u8 key[16];
245+
u8 name[64];
246+
u8 data8[16];
247+
u16 data16[8];
248+
u32 data32[4];
249+
u64 data64[2];
250+
};
251+
194252
struct ib_sa_query;
195253

196254
void ib_sa_cancel_query(int id, struct ib_sa_query *query);
@@ -216,6 +274,17 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
216274
void *context,
217275
struct ib_sa_query **query);
218276

277+
int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
278+
u8 method,
279+
struct ib_sa_service_rec *rec,
280+
ib_sa_comp_mask comp_mask,
281+
int timeout_ms, int gfp_mask,
282+
void (*callback)(int status,
283+
struct ib_sa_service_rec *resp,
284+
void *context),
285+
void *context,
286+
struct ib_sa_query **sa_query);
287+
219288
/**
220289
* ib_sa_mcmember_rec_set - Start an MCMember set query
221290
* @device:device to send query on

0 commit comments

Comments
 (0)