Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sysfs.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses. You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  * Redistribution and use in source and binary forms, with or
11  * without modification, are permitted provided that the following
12  * conditions are met:
13  *
14  * - Redistributions of source code must retain the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above
19  * copyright notice, this list of conditions and the following
20  * disclaimer in the documentation and/or other materials
21  * provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 /*#include "core_priv.h"*/
34 #include "mlx4_ib.h"
35 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
38 
39 #include <rdma/ib_mad.h>
40 /*show_admin_alias_guid returns the administratively assigned value of that GUID.
41  * Values returned in buf parameter string:
42  * 0 - requests opensm to assign a value.
43  * ffffffffffffffff - delete this entry.
44  * other - value assigned by administrator.
45  */
46 static ssize_t show_admin_alias_guid(struct device *dev,
47  struct device_attribute *attr, char *buf)
48 {
49  int record_num;/*0-15*/
50  int guid_index_in_rec; /*0 - 7*/
51  struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
53  struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
54  struct mlx4_ib_dev *mdev = port->dev;
55 
56  record_num = mlx4_ib_iov_dentry->entry_num / 8 ;
57  guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8 ;
58 
59  return sprintf(buf, "%llx\n",
60  be64_to_cpu(*(__be64 *)&mdev->sriov.alias_guid.
61  ports_guid[port->num - 1].
62  all_rec_per_port[record_num].
63  all_recs[8 * guid_index_in_rec]));
64 }
65 
66 /* store_admin_alias_guid stores the (new) administratively assigned value of that GUID.
67  * Values in buf parameter string:
68  * 0 - requests opensm to assign a value.
69  * 0xffffffffffffffff - delete this entry.
70  * other - guid value assigned by the administrator.
71  */
72 static ssize_t store_admin_alias_guid(struct device *dev,
73  struct device_attribute *attr,
74  const char *buf, size_t count)
75 {
76  int record_num;/*0-15*/
77  int guid_index_in_rec; /*0 - 7*/
78  struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
80  struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
81  struct mlx4_ib_dev *mdev = port->dev;
82  u64 sysadmin_ag_val;
83 
84  record_num = mlx4_ib_iov_dentry->entry_num / 8;
85  guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8;
86  if (0 == record_num && 0 == guid_index_in_rec) {
87  pr_err("GUID 0 block 0 is RO\n");
88  return count;
89  }
90  sscanf(buf, "%llx", &sysadmin_ag_val);
91  *(__be64 *)&mdev->sriov.alias_guid.ports_guid[port->num - 1].
92  all_rec_per_port[record_num].
93  all_recs[GUID_REC_SIZE * guid_index_in_rec] =
94  cpu_to_be64(sysadmin_ag_val);
95 
96  /* Change the state to be pending for update */
97  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].status
99 
100  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].method
102 
103  switch (sysadmin_ag_val) {
105  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].method
107  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].ownership
109  break;
110  /* The sysadmin requests the SM to re-assign */
111  case MLX4_NOT_SET_GUID:
112  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].ownership
114  break;
115  /* The sysadmin requests a specific value.*/
116  default:
117  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].ownership
119  break;
120  }
121 
122  /* set the record index */
123  mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].guid_indexes
124  = mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec);
125 
126  mlx4_ib_init_alias_guid_work(mdev, port->num - 1);
127 
128  return count;
129 }
130 
131 static ssize_t show_port_gid(struct device *dev,
132  struct device_attribute *attr,
133  char *buf)
134 {
135  struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
137  struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
138  struct mlx4_ib_dev *mdev = port->dev;
139  union ib_gid gid;
140  ssize_t ret;
141 
142  ret = __mlx4_ib_query_gid(&mdev->ib_dev, port->num,
143  mlx4_ib_iov_dentry->entry_num, &gid, 1);
144  if (ret)
145  return ret;
146  ret = sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
147  be16_to_cpu(((__be16 *) gid.raw)[0]),
148  be16_to_cpu(((__be16 *) gid.raw)[1]),
149  be16_to_cpu(((__be16 *) gid.raw)[2]),
150  be16_to_cpu(((__be16 *) gid.raw)[3]),
151  be16_to_cpu(((__be16 *) gid.raw)[4]),
152  be16_to_cpu(((__be16 *) gid.raw)[5]),
153  be16_to_cpu(((__be16 *) gid.raw)[6]),
154  be16_to_cpu(((__be16 *) gid.raw)[7]));
155  return ret;
156 }
157 
158 static ssize_t show_phys_port_pkey(struct device *dev,
159  struct device_attribute *attr,
160  char *buf)
161 {
162  struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
164  struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
165  struct mlx4_ib_dev *mdev = port->dev;
166  u16 pkey;
167  ssize_t ret;
168 
169  ret = __mlx4_ib_query_pkey(&mdev->ib_dev, port->num,
170  mlx4_ib_iov_dentry->entry_num, &pkey, 1);
171  if (ret)
172  return ret;
173 
174  return sprintf(buf, "0x%04x\n", pkey);
175 }
176 
177 #define DENTRY_REMOVE(_dentry) \
178 do { \
179  sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr); \
180 } while (0);
181 
182 static int create_sysfs_entry(void *_ctx, struct mlx4_ib_iov_sysfs_attr *_dentry,
183  char *_name, struct kobject *_kobj,
184  ssize_t (*show)(struct device *dev,
185  struct device_attribute *attr,
186  char *buf),
187  ssize_t (*store)(struct device *dev,
188  struct device_attribute *attr,
189  const char *buf, size_t count)
190  )
191 {
192  int ret = 0;
193  struct mlx4_ib_iov_sysfs_attr *vdentry = _dentry;
194 
195  vdentry->ctx = _ctx;
196  vdentry->dentry.show = show;
197  vdentry->dentry.store = store;
198  sysfs_attr_init(&vdentry->dentry.attr);
199  vdentry->dentry.attr.name = vdentry->name;
200  vdentry->dentry.attr.mode = 0;
201  vdentry->kobj = _kobj;
202  snprintf(vdentry->name, 15, "%s", _name);
203 
204  if (vdentry->dentry.store)
205  vdentry->dentry.attr.mode |= S_IWUSR;
206 
207  if (vdentry->dentry.show)
208  vdentry->dentry.attr.mode |= S_IRUGO;
209 
210  ret = sysfs_create_file(vdentry->kobj, &vdentry->dentry.attr);
211  if (ret) {
212  pr_err("failed to create %s\n", vdentry->dentry.attr.name);
213  vdentry->ctx = NULL;
214  return ret;
215  }
216 
217  return ret;
218 }
219 
221  struct attribute *attr)
222 {
223  struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
224  int ret;
225 
226  ret = sysfs_create_file(port->mcgs_parent, attr);
227  if (ret)
228  pr_err("failed to create %s\n", attr->name);
229 
230  return ret;
231 }
232 
234  struct attribute *attr)
235 {
236  struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
237 
238  sysfs_remove_file(port->mcgs_parent, attr);
239 }
240 
241 static int add_port_entries(struct mlx4_ib_dev *device, int port_num)
242 {
243  int i;
244  char buff[10];
245  struct mlx4_ib_iov_port *port = NULL;
246  int ret = 0 ;
247  struct ib_port_attr attr;
248 
249  /* get the physical gid and pkey table sizes.*/
250  ret = __mlx4_ib_query_port(&device->ib_dev, port_num, &attr, 1);
251  if (ret)
252  goto err;
253 
254  port = &device->iov_ports[port_num - 1];
255  port->dev = device;
256  port->num = port_num;
257  /* Directory structure:
258  * iov -
259  * port num -
260  * admin_guids
261  * gids (operational)
262  * mcg_table
263  */
264  port->dentr_ar = kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar),
265  GFP_KERNEL);
266  if (!port->dentr_ar) {
267  ret = -ENOMEM;
268  goto err;
269  }
270  sprintf(buff, "%d", port_num);
271  port->cur_port = kobject_create_and_add(buff,
272  kobject_get(device->ports_parent));
273  if (!port->cur_port) {
274  ret = -ENOMEM;
275  goto kobj_create_err;
276  }
277  /* admin GUIDs */
278  port->admin_alias_parent = kobject_create_and_add("admin_guids",
279  kobject_get(port->cur_port));
280  if (!port->admin_alias_parent) {
281  ret = -ENOMEM;
282  goto err_admin_guids;
283  }
284  for (i = 0 ; i < attr.gid_tbl_len; i++) {
285  sprintf(buff, "%d", i);
286  port->dentr_ar->dentries[i].entry_num = i;
287  ret = create_sysfs_entry(port, &port->dentr_ar->dentries[i],
288  buff, port->admin_alias_parent,
289  show_admin_alias_guid, store_admin_alias_guid);
290  if (ret)
291  goto err_admin_alias_parent;
292  }
293 
294  /* gids subdirectory (operational gids) */
295  port->gids_parent = kobject_create_and_add("gids",
296  kobject_get(port->cur_port));
297  if (!port->gids_parent) {
298  ret = -ENOMEM;
299  goto err_gids;
300  }
301 
302  for (i = 0 ; i < attr.gid_tbl_len; i++) {
303  sprintf(buff, "%d", i);
304  port->dentr_ar->dentries[attr.gid_tbl_len + i].entry_num = i;
305  ret = create_sysfs_entry(port,
306  &port->dentr_ar->dentries[attr.gid_tbl_len + i],
307  buff,
308  port->gids_parent, show_port_gid, NULL);
309  if (ret)
310  goto err_gids_parent;
311  }
312 
313  /* physical port pkey table */
314  port->pkeys_parent =
316  if (!port->pkeys_parent) {
317  ret = -ENOMEM;
318  goto err_pkeys;
319  }
320 
321  for (i = 0 ; i < attr.pkey_tbl_len; i++) {
322  sprintf(buff, "%d", i);
323  port->dentr_ar->dentries[2 * attr.gid_tbl_len + i].entry_num = i;
324  ret = create_sysfs_entry(port,
325  &port->dentr_ar->dentries[2 * attr.gid_tbl_len + i],
326  buff, port->pkeys_parent,
327  show_phys_port_pkey, NULL);
328  if (ret)
329  goto err_pkeys_parent;
330  }
331 
332  /* MCGs table */
333  port->mcgs_parent =
335  if (!port->mcgs_parent) {
336  ret = -ENOMEM;
337  goto err_mcgs;
338  }
339  return 0;
340 
341 err_mcgs:
342  kobject_put(port->cur_port);
343 
344 err_pkeys_parent:
345  kobject_put(port->pkeys_parent);
346 
347 err_pkeys:
348  kobject_put(port->cur_port);
349 
350 err_gids_parent:
351  kobject_put(port->gids_parent);
352 
353 err_gids:
354  kobject_put(port->cur_port);
355 
356 err_admin_alias_parent:
358 
359 err_admin_guids:
360  kobject_put(port->cur_port);
361  kobject_put(port->cur_port); /* once more for create_and_add buff */
362 
363 kobj_create_err:
364  kobject_put(device->ports_parent);
365  kfree(port->dentr_ar);
366 
367 err:
368  pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
369  port_num, ret);
370  return ret;
371 }
372 
373 static void get_name(struct mlx4_ib_dev *dev, char *name, int i, int max)
374 {
375  char base_name[9];
376 
377  /* pci_name format is: bus:dev:func -> xxxx:yy:zz.n */
378  strlcpy(name, pci_name(dev->dev->pdev), max);
379  strncpy(base_name, name, 8); /*till xxxx:yy:*/
380  base_name[8] = '\0';
381  /* with no ARI only 3 last bits are used so when the fn is higher than 8
382  * need to add it to the dev num, so count in the last number will be
383  * modulo 8 */
384  sprintf(name, "%s%.2d.%d", base_name, (i/8), (i%8));
385 }
386 
387 struct mlx4_port {
388  struct kobject kobj;
389  struct mlx4_ib_dev *dev;
393  int slave;
394 };
395 
396 
397 static void mlx4_port_release(struct kobject *kobj)
398 {
399  struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
400  struct attribute *a;
401  int i;
402 
403  for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
404  kfree(a);
405  kfree(p->pkey_group.attrs);
406  for (i = 0; (a = p->gid_group.attrs[i]); ++i)
407  kfree(a);
408  kfree(p->gid_group.attrs);
409  kfree(p);
410 }
411 
412 struct port_attribute {
413  struct attribute attr;
414  ssize_t (*show)(struct mlx4_port *, struct port_attribute *, char *buf);
415  ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
416  const char *buf, size_t count);
417 };
418 
419 static ssize_t port_attr_show(struct kobject *kobj,
420  struct attribute *attr, char *buf)
421 {
422  struct port_attribute *port_attr =
423  container_of(attr, struct port_attribute, attr);
424  struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
425 
426  if (!port_attr->show)
427  return -EIO;
428  return port_attr->show(p, port_attr, buf);
429 }
430 
431 static ssize_t port_attr_store(struct kobject *kobj,
432  struct attribute *attr,
433  const char *buf, size_t size)
434 {
435  struct port_attribute *port_attr =
436  container_of(attr, struct port_attribute, attr);
437  struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
438 
439  if (!port_attr->store)
440  return -EIO;
441  return port_attr->store(p, port_attr, buf, size);
442 }
443 
444 static const struct sysfs_ops port_sysfs_ops = {
445  .show = port_attr_show,
446  .store = port_attr_store,
447 };
448 
449 static struct kobj_type port_type = {
450  .release = mlx4_port_release,
451  .sysfs_ops = &port_sysfs_ops,
452 };
453 
454 struct port_table_attribute {
455  struct port_attribute attr;
456  char name[8];
457  int index;
458 };
459 
460 static ssize_t show_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
461  char *buf)
462 {
463  struct port_table_attribute *tab_attr =
464  container_of(attr, struct port_table_attribute, attr);
465  ssize_t ret = -ENODEV;
466 
467  if (p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1][tab_attr->index] >=
468  (p->dev->dev->caps.pkey_table_len[p->port_num]))
469  ret = sprintf(buf, "none\n");
470  else
471  ret = sprintf(buf, "%d\n",
472  p->dev->pkeys.virt2phys_pkey[p->slave]
473  [p->port_num - 1][tab_attr->index]);
474  return ret;
475 }
476 
477 static ssize_t store_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
478  const char *buf, size_t count)
479 {
480  struct port_table_attribute *tab_attr =
481  container_of(attr, struct port_table_attribute, attr);
482  int idx;
483  int err;
484 
485  /* do not allow remapping Dom0 virtual pkey table */
486  if (p->slave == mlx4_master_func_num(p->dev->dev))
487  return -EINVAL;
488 
489  if (!strncasecmp(buf, "no", 2))
490  idx = p->dev->dev->phys_caps.pkey_phys_table_len[p->port_num] - 1;
491  else if (sscanf(buf, "%i", &idx) != 1 ||
492  idx >= p->dev->dev->caps.pkey_table_len[p->port_num] ||
493  idx < 0)
494  return -EINVAL;
495 
496  p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1]
497  [tab_attr->index] = idx;
498  mlx4_sync_pkey_table(p->dev->dev, p->slave, p->port_num,
499  tab_attr->index, idx);
500  err = mlx4_gen_pkey_eqe(p->dev->dev, p->slave, p->port_num);
501  if (err) {
502  pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
503  " port %d, index %d\n", p->slave, p->port_num, idx);
504  return err;
505  }
506  return count;
507 }
508 
509 static ssize_t show_port_gid_idx(struct mlx4_port *p,
510  struct port_attribute *attr, char *buf)
511 {
512  return sprintf(buf, "%d\n", p->slave);
513 }
514 
515 static struct attribute **
516 alloc_group_attrs(ssize_t (*show)(struct mlx4_port *,
517  struct port_attribute *, char *buf),
518  ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
519  const char *buf, size_t count),
520  int len)
521 {
522  struct attribute **tab_attr;
524  int i;
525 
526  tab_attr = kcalloc(1 + len, sizeof (struct attribute *), GFP_KERNEL);
527  if (!tab_attr)
528  return NULL;
529 
530  for (i = 0; i < len; i++) {
531  element = kzalloc(sizeof (struct port_table_attribute),
532  GFP_KERNEL);
533  if (!element)
534  goto err;
535  if (snprintf(element->name, sizeof (element->name),
536  "%d", i) >= sizeof (element->name)) {
537  kfree(element);
538  goto err;
539  }
540  sysfs_attr_init(&element->attr.attr);
541  element->attr.attr.name = element->name;
542  if (store) {
543  element->attr.attr.mode = S_IWUSR | S_IRUGO;
544  element->attr.store = store;
545  } else
546  element->attr.attr.mode = S_IRUGO;
547 
548  element->attr.show = show;
549  element->index = i;
550  tab_attr[i] = &element->attr.attr;
551  }
552  return tab_attr;
553 
554 err:
555  while (--i >= 0)
556  kfree(tab_attr[i]);
557  kfree(tab_attr);
558  return NULL;
559 }
560 
561 static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
562 {
563  struct mlx4_port *p;
564  int i;
565  int ret;
566 
567  p = kzalloc(sizeof *p, GFP_KERNEL);
568  if (!p)
569  return -ENOMEM;
570 
571  p->dev = dev;
572  p->port_num = port_num;
573  p->slave = slave;
574 
575  ret = kobject_init_and_add(&p->kobj, &port_type,
576  kobject_get(dev->dev_ports_parent[slave]),
577  "%d", port_num);
578  if (ret)
579  goto err_alloc;
580 
581  p->pkey_group.name = "pkey_idx";
582  p->pkey_group.attrs =
583  alloc_group_attrs(show_port_pkey, store_port_pkey,
584  dev->dev->caps.pkey_table_len[port_num]);
585  if (!p->pkey_group.attrs)
586  goto err_alloc;
587 
588  ret = sysfs_create_group(&p->kobj, &p->pkey_group);
589  if (ret)
590  goto err_free_pkey;
591 
592  p->gid_group.name = "gid_idx";
593  p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
594  if (!p->gid_group.attrs)
595  goto err_free_pkey;
596 
597  ret = sysfs_create_group(&p->kobj, &p->gid_group);
598  if (ret)
599  goto err_free_gid;
600 
601  list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]);
602  return 0;
603 
604 err_free_gid:
605  kfree(p->gid_group.attrs[0]);
606  kfree(p->gid_group.attrs);
607 
608 err_free_pkey:
609  for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i)
610  kfree(p->pkey_group.attrs[i]);
611  kfree(p->pkey_group.attrs);
612 
613 err_alloc:
614  kobject_put(dev->dev_ports_parent[slave]);
615  kfree(p);
616  return ret;
617 }
618 
619 static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
620 {
621  char name[32];
622  int err;
623  int port;
624  struct kobject *p, *t;
625  struct mlx4_port *mport;
626 
627  get_name(dev, name, slave, sizeof name);
628 
629  dev->pkeys.device_parent[slave] =
631 
632  if (!dev->pkeys.device_parent[slave]) {
633  err = -ENOMEM;
634  goto fail_dev;
635  }
636 
637  INIT_LIST_HEAD(&dev->pkeys.pkey_port_list[slave]);
638 
639  dev->dev_ports_parent[slave] =
640  kobject_create_and_add("ports",
641  kobject_get(dev->pkeys.device_parent[slave]));
642 
643  if (!dev->dev_ports_parent[slave]) {
644  err = -ENOMEM;
645  goto err_ports;
646  }
647 
648  for (port = 1; port <= dev->dev->caps.num_ports; ++port) {
649  err = add_port(dev, port, slave);
650  if (err)
651  goto err_add;
652  }
653  return 0;
654 
655 err_add:
657  &dev->pkeys.pkey_port_list[slave],
658  entry) {
659  list_del(&p->entry);
660  mport = container_of(p, struct mlx4_port, kobj);
661  sysfs_remove_group(p, &mport->pkey_group);
662  sysfs_remove_group(p, &mport->gid_group);
663  kobject_put(p);
664  }
665  kobject_put(dev->dev_ports_parent[slave]);
666 
667 err_ports:
668  kobject_put(dev->pkeys.device_parent[slave]);
669  /* extra put for the device_parent create_and_add */
670  kobject_put(dev->pkeys.device_parent[slave]);
671 
672 fail_dev:
673  kobject_put(dev->iov_parent);
674  return err;
675 }
676 
677 static int register_pkey_tree(struct mlx4_ib_dev *device)
678 {
679  int i;
680 
681  if (!mlx4_is_master(device->dev))
682  return 0;
683 
684  for (i = 0; i <= device->dev->num_vfs; ++i)
685  register_one_pkey_tree(device, i);
686 
687  return 0;
688 }
689 
690 static void unregister_pkey_tree(struct mlx4_ib_dev *device)
691 {
692  int slave;
693  struct kobject *p, *t;
694  struct mlx4_port *port;
695 
696  if (!mlx4_is_master(device->dev))
697  return;
698 
699  for (slave = device->dev->num_vfs; slave >= 0; --slave) {
701  &device->pkeys.pkey_port_list[slave],
702  entry) {
703  list_del(&p->entry);
704  port = container_of(p, struct mlx4_port, kobj);
705  sysfs_remove_group(p, &port->pkey_group);
706  sysfs_remove_group(p, &port->gid_group);
707  kobject_put(p);
708  kobject_put(device->dev_ports_parent[slave]);
709  }
710  kobject_put(device->dev_ports_parent[slave]);
711  kobject_put(device->pkeys.device_parent[slave]);
712  kobject_put(device->pkeys.device_parent[slave]);
713  kobject_put(device->iov_parent);
714  }
715 }
716 
718 {
719  int i;
720  int ret = 0;
721 
722  if (!mlx4_is_master(dev->dev))
723  return 0;
724 
725  dev->iov_parent =
727  kobject_get(dev->ib_dev.ports_parent->parent));
728  if (!dev->iov_parent) {
729  ret = -ENOMEM;
730  goto err;
731  }
732  dev->ports_parent =
733  kobject_create_and_add("ports",
734  kobject_get(dev->iov_parent));
735  if (!dev->iov_parent) {
736  ret = -ENOMEM;
737  goto err_ports;
738  }
739 
740  for (i = 1; i <= dev->ib_dev.phys_port_cnt; ++i) {
741  ret = add_port_entries(dev, i);
742  if (ret)
743  goto err_add_entries;
744  }
745 
746  ret = register_pkey_tree(dev);
747  if (ret)
748  goto err_add_entries;
749  return 0;
750 
751 err_add_entries:
753 
754 err_ports:
755  kobject_put(dev->iov_parent);
756 err:
757  kobject_put(dev->ib_dev.ports_parent->parent);
758  pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret);
759  return ret;
760 }
761 
762 static void unregister_alias_guid_tree(struct mlx4_ib_dev *device)
763 {
764  struct mlx4_ib_iov_port *p;
765  int i;
766 
767  if (!mlx4_is_master(device->dev))
768  return;
769 
770  for (i = 0; i < device->dev->caps.num_ports; i++) {
771  p = &device->iov_ports[i];
776  kobject_put(p->cur_port);
777  kobject_put(p->cur_port);
778  kobject_put(p->cur_port);
779  kobject_put(p->cur_port);
780  kobject_put(p->cur_port);
781  kobject_put(p->dev->ports_parent);
782  kfree(p->dentr_ar);
783  }
784 }
785 
787 {
788  unregister_alias_guid_tree(device);
789  unregister_pkey_tree(device);
790  kobject_put(device->ports_parent);
791  kobject_put(device->iov_parent);
792  kobject_put(device->iov_parent);
793  kobject_put(device->ib_dev.ports_parent->parent);
794 }