aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/device.c125
-rw-r--r--include/rdma/ib_verbs.h8
2 files changed, 133 insertions, 0 deletions
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 592c90aa3183..b448e0b2b6b4 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -149,6 +149,18 @@ static int alloc_name(char *name)
149 return 0; 149 return 0;
150} 150}
151 151
152static int start_port(struct ib_device *device)
153{
154 return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1;
155}
156
157
158static int end_port(struct ib_device *device)
159{
160 return (device->node_type == RDMA_NODE_IB_SWITCH) ?
161 0 : device->phys_port_cnt;
162}
163
152/** 164/**
153 * ib_alloc_device - allocate an IB device struct 165 * ib_alloc_device - allocate an IB device struct
154 * @size:size of structure to allocate 166 * @size:size of structure to allocate
@@ -208,6 +220,45 @@ static int add_client_context(struct ib_device *device, struct ib_client *client
208 return 0; 220 return 0;
209} 221}
210 222
223static int read_port_table_lengths(struct ib_device *device)
224{
225 struct ib_port_attr *tprops = NULL;
226 int num_ports, ret = -ENOMEM;
227 u8 port_index;
228
229 tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
230 if (!tprops)
231 goto out;
232
233 num_ports = end_port(device) - start_port(device) + 1;
234
235 device->pkey_tbl_len = kmalloc(sizeof *device->pkey_tbl_len * num_ports,
236 GFP_KERNEL);
237 device->gid_tbl_len = kmalloc(sizeof *device->gid_tbl_len * num_ports,
238 GFP_KERNEL);
239 if (!device->pkey_tbl_len || !device->gid_tbl_len)
240 goto err;
241
242 for (port_index = 0; port_index < num_ports; ++port_index) {
243 ret = ib_query_port(device, port_index + start_port(device),
244 tprops);
245 if (ret)
246 goto err;
247 device->pkey_tbl_len[port_index] = tprops->pkey_tbl_len;
248 device->gid_tbl_len[port_index] = tprops->gid_tbl_len;
249 }
250
251 ret = 0;
252 goto out;
253
254err:
255 kfree(device->gid_tbl_len);
256 kfree(device->pkey_tbl_len);
257out:
258 kfree(tprops);
259 return ret;
260}
261
211/** 262/**
212 * ib_register_device - Register an IB device with IB core 263 * ib_register_device - Register an IB device with IB core
213 * @device:Device to register 264 * @device:Device to register
@@ -239,10 +290,19 @@ int ib_register_device(struct ib_device *device)
239 spin_lock_init(&device->event_handler_lock); 290 spin_lock_init(&device->event_handler_lock);
240 spin_lock_init(&device->client_data_lock); 291 spin_lock_init(&device->client_data_lock);
241 292
293 ret = read_port_table_lengths(device);
294 if (ret) {
295 printk(KERN_WARNING "Couldn't create table lengths cache for device %s\n",
296 device->name);
297 goto out;
298 }
299
242 ret = ib_device_register_sysfs(device); 300 ret = ib_device_register_sysfs(device);
243 if (ret) { 301 if (ret) {
244 printk(KERN_WARNING "Couldn't register device %s with driver model\n", 302 printk(KERN_WARNING "Couldn't register device %s with driver model\n",
245 device->name); 303 device->name);
304 kfree(device->gid_tbl_len);
305 kfree(device->pkey_tbl_len);
246 goto out; 306 goto out;
247 } 307 }
248 308
@@ -284,6 +344,9 @@ void ib_unregister_device(struct ib_device *device)
284 344
285 list_del(&device->core_list); 345 list_del(&device->core_list);
286 346
347 kfree(device->gid_tbl_len);
348 kfree(device->pkey_tbl_len);
349
287 mutex_unlock(&device_mutex); 350 mutex_unlock(&device_mutex);
288 351
289 spin_lock_irqsave(&device->client_data_lock, flags); 352 spin_lock_irqsave(&device->client_data_lock, flags);
@@ -592,6 +655,68 @@ int ib_modify_port(struct ib_device *device,
592} 655}
593EXPORT_SYMBOL(ib_modify_port); 656EXPORT_SYMBOL(ib_modify_port);
594 657
658/**
659 * ib_find_gid - Returns the port number and GID table index where
660 * a specified GID value occurs.
661 * @device: The device to query.
662 * @gid: The GID value to search for.
663 * @port_num: The port number of the device where the GID value was found.
664 * @index: The index into the GID table where the GID was found. This
665 * parameter may be NULL.
666 */
667int ib_find_gid(struct ib_device *device, union ib_gid *gid,
668 u8 *port_num, u16 *index)
669{
670 union ib_gid tmp_gid;
671 int ret, port, i;
672
673 for (port = start_port(device); port <= end_port(device); ++port) {
674 for (i = 0; i < device->gid_tbl_len[port - start_port(device)]; ++i) {
675 ret = ib_query_gid(device, port, i, &tmp_gid);
676 if (ret)
677 return ret;
678 if (!memcmp(&tmp_gid, gid, sizeof *gid)) {
679 *port_num = port;
680 if (index)
681 *index = i;
682 return 0;
683 }
684 }
685 }
686
687 return -ENOENT;
688}
689EXPORT_SYMBOL(ib_find_gid);
690
691/**
692 * ib_find_pkey - Returns the PKey table index where a specified
693 * PKey value occurs.
694 * @device: The device to query.
695 * @port_num: The port number of the device to search for the PKey.
696 * @pkey: The PKey value to search for.
697 * @index: The index into the PKey table where the PKey was found.
698 */
699int ib_find_pkey(struct ib_device *device,
700 u8 port_num, u16 pkey, u16 *index)
701{
702 int ret, i;
703 u16 tmp_pkey;
704
705 for (i = 0; i < device->pkey_tbl_len[port_num - start_port(device)]; ++i) {
706 ret = ib_query_pkey(device, port_num, i, &tmp_pkey);
707 if (ret)
708 return ret;
709
710 if (pkey == tmp_pkey) {
711 *index = i;
712 return 0;
713 }
714 }
715
716 return -ENOENT;
717}
718EXPORT_SYMBOL(ib_find_pkey);
719
595static int __init ib_core_init(void) 720static int __init ib_core_init(void)
596{ 721{
597 int ret; 722 int ret;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 47cefca59c89..0627a6aa282a 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -890,6 +890,8 @@ struct ib_device {
890 spinlock_t client_data_lock; 890 spinlock_t client_data_lock;
891 891
892 struct ib_cache cache; 892 struct ib_cache cache;
893 int *pkey_tbl_len;
894 int *gid_tbl_len;
893 895
894 u32 flags; 896 u32 flags;
895 897
@@ -1118,6 +1120,12 @@ int ib_modify_port(struct ib_device *device,
1118 u8 port_num, int port_modify_mask, 1120 u8 port_num, int port_modify_mask,
1119 struct ib_port_modify *port_modify); 1121 struct ib_port_modify *port_modify);
1120 1122
1123int ib_find_gid(struct ib_device *device, union ib_gid *gid,
1124 u8 *port_num, u16 *index);
1125
1126int ib_find_pkey(struct ib_device *device,
1127 u8 port_num, u16 pkey, u16 *index);
1128
1121/** 1129/**
1122 * ib_alloc_pd - Allocates an unused protection domain. 1130 * ib_alloc_pd - Allocates an unused protection domain.
1123 * @device: The device on which to allocate the protection domain. 1131 * @device: The device on which to allocate the protection domain.