2 * Copyright (c) 2012 Mellanox Technologies. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
33 /*#include "core_priv.h"*/
35 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
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.
46 static ssize_t
show_admin_alias_guid(struct device
*dev
,
47 struct device_attribute
*attr
, char *buf
)
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
=
52 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
53 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
54 struct mlx4_ib_dev
*mdev
= port
->dev
;
56 record_num
= mlx4_ib_iov_dentry
->entry_num
/ 8 ;
57 guid_index_in_rec
= mlx4_ib_iov_dentry
->entry_num
% 8 ;
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
]));
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.
72 static ssize_t
store_admin_alias_guid(struct device
*dev
,
73 struct device_attribute
*attr
,
74 const char *buf
, size_t count
)
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
=
79 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
80 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
81 struct mlx4_ib_dev
*mdev
= port
->dev
;
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");
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
);
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
98 = MLX4_GUID_INFO_STATUS_IDLE
;
100 mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].all_rec_per_port
[record_num
].method
101 = MLX4_GUID_INFO_RECORD_SET
;
103 switch (sysadmin_ag_val
) {
104 case MLX4_GUID_FOR_DELETE_VAL
:
105 mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].all_rec_per_port
[record_num
].method
106 = MLX4_GUID_INFO_RECORD_DELETE
;
107 mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].all_rec_per_port
[record_num
].ownership
108 = MLX4_GUID_SYSADMIN_ASSIGN
;
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
113 = MLX4_GUID_DRIVER_ASSIGN
;
115 /* The sysadmin requests a specific value.*/
117 mdev
->sriov
.alias_guid
.ports_guid
[port
->num
- 1].all_rec_per_port
[record_num
].ownership
118 = MLX4_GUID_SYSADMIN_ASSIGN
;
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
);
126 mlx4_ib_init_alias_guid_work(mdev
, port
->num
- 1);
131 static ssize_t
show_port_gid(struct device
*dev
,
132 struct device_attribute
*attr
,
135 struct mlx4_ib_iov_sysfs_attr
*mlx4_ib_iov_dentry
=
136 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
137 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
138 struct mlx4_ib_dev
*mdev
= port
->dev
;
142 ret
= __mlx4_ib_query_gid(&mdev
->ib_dev
, port
->num
,
143 mlx4_ib_iov_dentry
->entry_num
, &gid
, 1);
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]));
158 static ssize_t
show_phys_port_pkey(struct device
*dev
,
159 struct device_attribute
*attr
,
162 struct mlx4_ib_iov_sysfs_attr
*mlx4_ib_iov_dentry
=
163 container_of(attr
, struct mlx4_ib_iov_sysfs_attr
, dentry
);
164 struct mlx4_ib_iov_port
*port
= mlx4_ib_iov_dentry
->ctx
;
165 struct mlx4_ib_dev
*mdev
= port
->dev
;
169 ret
= __mlx4_ib_query_pkey(&mdev
->ib_dev
, port
->num
,
170 mlx4_ib_iov_dentry
->entry_num
, &pkey
, 1);
174 return sprintf(buf
, "0x%04x\n", pkey
);
177 #define DENTRY_REMOVE(_dentry) \
179 sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr); \
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
,
187 ssize_t (*store
)(struct device
*dev
,
188 struct device_attribute
*attr
,
189 const char *buf
, size_t count
)
193 struct mlx4_ib_iov_sysfs_attr
*vdentry
= _dentry
;
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
);
204 if (vdentry
->dentry
.store
)
205 vdentry
->dentry
.attr
.mode
|= S_IWUSR
;
207 if (vdentry
->dentry
.show
)
208 vdentry
->dentry
.attr
.mode
|= S_IRUGO
;
210 ret
= sysfs_create_file(vdentry
->kobj
, &vdentry
->dentry
.attr
);
212 pr_err("failed to create %s\n", vdentry
->dentry
.attr
.name
);
220 int add_sysfs_port_mcg_attr(struct mlx4_ib_dev
*device
, int port_num
,
221 struct attribute
*attr
)
223 struct mlx4_ib_iov_port
*port
= &device
->iov_ports
[port_num
- 1];
226 ret
= sysfs_create_file(port
->mcgs_parent
, attr
);
228 pr_err("failed to create %s\n", attr
->name
);
233 void del_sysfs_port_mcg_attr(struct mlx4_ib_dev
*device
, int port_num
,
234 struct attribute
*attr
)
236 struct mlx4_ib_iov_port
*port
= &device
->iov_ports
[port_num
- 1];
238 sysfs_remove_file(port
->mcgs_parent
, attr
);
241 static int add_port_entries(struct mlx4_ib_dev
*device
, int port_num
)
245 struct mlx4_ib_iov_port
*port
= NULL
;
247 struct ib_port_attr attr
;
249 /* get the physical gid and pkey table sizes.*/
250 ret
= __mlx4_ib_query_port(&device
->ib_dev
, port_num
, &attr
, 1);
254 port
= &device
->iov_ports
[port_num
- 1];
256 port
->num
= port_num
;
257 /* Directory structure:
264 port
->dentr_ar
= kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar
),
266 if (!port
->dentr_ar
) {
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
) {
275 goto kobj_create_err
;
278 port
->admin_alias_parent
= kobject_create_and_add("admin_guids",
279 kobject_get(port
->cur_port
));
280 if (!port
->admin_alias_parent
) {
282 goto err_admin_guids
;
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
);
291 goto err_admin_alias_parent
;
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
) {
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
],
308 port
->gids_parent
, show_port_gid
, NULL
);
310 goto err_gids_parent
;
313 /* physical port pkey table */
315 kobject_create_and_add("pkeys", kobject_get(port
->cur_port
));
316 if (!port
->pkeys_parent
) {
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
);
329 goto err_pkeys_parent
;
334 kobject_create_and_add("mcgs", kobject_get(port
->cur_port
));
335 if (!port
->mcgs_parent
) {
342 kobject_put(port
->cur_port
);
345 kobject_put(port
->pkeys_parent
);
348 kobject_put(port
->cur_port
);
351 kobject_put(port
->gids_parent
);
354 kobject_put(port
->cur_port
);
356 err_admin_alias_parent
:
357 kobject_put(port
->admin_alias_parent
);
360 kobject_put(port
->cur_port
);
361 kobject_put(port
->cur_port
); /* once more for create_and_add buff */
364 kobject_put(device
->ports_parent
);
365 kfree(port
->dentr_ar
);
368 pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
373 static void get_name(struct mlx4_ib_dev
*dev
, char *name
, int i
, int max
)
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:*/
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
384 sprintf(name
, "%s%.2d.%d", base_name
, (i
/8), (i
%8));
389 struct mlx4_ib_dev
*dev
;
390 struct attribute_group pkey_group
;
391 struct attribute_group gid_group
;
397 static void mlx4_port_release(struct kobject
*kobj
)
399 struct mlx4_port
*p
= container_of(kobj
, struct mlx4_port
, kobj
);
403 for (i
= 0; (a
= p
->pkey_group
.attrs
[i
]); ++i
)
405 kfree(p
->pkey_group
.attrs
);
406 for (i
= 0; (a
= p
->gid_group
.attrs
[i
]); ++i
)
408 kfree(p
->gid_group
.attrs
);
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
);
419 static ssize_t
port_attr_show(struct kobject
*kobj
,
420 struct attribute
*attr
, char *buf
)
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
);
426 if (!port_attr
->show
)
428 return port_attr
->show(p
, port_attr
, buf
);
431 static ssize_t
port_attr_store(struct kobject
*kobj
,
432 struct attribute
*attr
,
433 const char *buf
, size_t size
)
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
);
439 if (!port_attr
->store
)
441 return port_attr
->store(p
, port_attr
, buf
, size
);
444 static const struct sysfs_ops port_sysfs_ops
= {
445 .show
= port_attr_show
,
446 .store
= port_attr_store
,
449 static struct kobj_type port_type
= {
450 .release
= mlx4_port_release
,
451 .sysfs_ops
= &port_sysfs_ops
,
454 struct port_table_attribute
{
455 struct port_attribute attr
;
460 static ssize_t
show_port_pkey(struct mlx4_port
*p
, struct port_attribute
*attr
,
463 struct port_table_attribute
*tab_attr
=
464 container_of(attr
, struct port_table_attribute
, attr
);
465 ssize_t ret
= -ENODEV
;
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");
471 ret
= sprintf(buf
, "%d\n",
472 p
->dev
->pkeys
.virt2phys_pkey
[p
->slave
]
473 [p
->port_num
- 1][tab_attr
->index
]);
477 static ssize_t
store_port_pkey(struct mlx4_port
*p
, struct port_attribute
*attr
,
478 const char *buf
, size_t count
)
480 struct port_table_attribute
*tab_attr
=
481 container_of(attr
, struct port_table_attribute
, attr
);
485 /* do not allow remapping Dom0 virtual pkey table */
486 if (p
->slave
== mlx4_master_func_num(p
->dev
->dev
))
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
] ||
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
);
502 pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
503 " port %d, index %d\n", p
->slave
, p
->port_num
, idx
);
509 static ssize_t
show_port_gid_idx(struct mlx4_port
*p
,
510 struct port_attribute
*attr
, char *buf
)
512 return sprintf(buf
, "%d\n", p
->slave
);
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
),
522 struct attribute
**tab_attr
;
523 struct port_table_attribute
*element
;
526 tab_attr
= kcalloc(1 + len
, sizeof (struct attribute
*), GFP_KERNEL
);
530 for (i
= 0; i
< len
; i
++) {
531 element
= kzalloc(sizeof (struct port_table_attribute
),
535 if (snprintf(element
->name
, sizeof (element
->name
),
536 "%d", i
) >= sizeof (element
->name
)) {
540 sysfs_attr_init(&element
->attr
.attr
);
541 element
->attr
.attr
.name
= element
->name
;
543 element
->attr
.attr
.mode
= S_IWUSR
| S_IRUGO
;
544 element
->attr
.store
= store
;
546 element
->attr
.attr
.mode
= S_IRUGO
;
548 element
->attr
.show
= show
;
550 tab_attr
[i
] = &element
->attr
.attr
;
561 static int add_port(struct mlx4_ib_dev
*dev
, int port_num
, int slave
)
567 p
= kzalloc(sizeof *p
, GFP_KERNEL
);
572 p
->port_num
= port_num
;
575 ret
= kobject_init_and_add(&p
->kobj
, &port_type
,
576 kobject_get(dev
->dev_ports_parent
[slave
]),
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
) {
590 ret
= sysfs_create_group(&p
->kobj
, &p
->pkey_group
);
594 p
->gid_group
.name
= "gid_idx";
595 p
->gid_group
.attrs
= alloc_group_attrs(show_port_gid_idx
, NULL
, 1);
596 if (!p
->gid_group
.attrs
) {
601 ret
= sysfs_create_group(&p
->kobj
, &p
->gid_group
);
605 list_add_tail(&p
->kobj
.entry
, &dev
->pkeys
.pkey_port_list
[slave
]);
609 kfree(p
->gid_group
.attrs
[0]);
610 kfree(p
->gid_group
.attrs
);
613 for (i
= 0; i
< dev
->dev
->caps
.pkey_table_len
[port_num
]; ++i
)
614 kfree(p
->pkey_group
.attrs
[i
]);
615 kfree(p
->pkey_group
.attrs
);
618 kobject_put(dev
->dev_ports_parent
[slave
]);
623 static int register_one_pkey_tree(struct mlx4_ib_dev
*dev
, int slave
)
628 struct kobject
*p
, *t
;
629 struct mlx4_port
*mport
;
631 get_name(dev
, name
, slave
, sizeof name
);
633 dev
->pkeys
.device_parent
[slave
] =
634 kobject_create_and_add(name
, kobject_get(dev
->iov_parent
));
636 if (!dev
->pkeys
.device_parent
[slave
]) {
641 INIT_LIST_HEAD(&dev
->pkeys
.pkey_port_list
[slave
]);
643 dev
->dev_ports_parent
[slave
] =
644 kobject_create_and_add("ports",
645 kobject_get(dev
->pkeys
.device_parent
[slave
]));
647 if (!dev
->dev_ports_parent
[slave
]) {
652 for (port
= 1; port
<= dev
->dev
->caps
.num_ports
; ++port
) {
653 err
= add_port(dev
, port
, slave
);
660 list_for_each_entry_safe(p
, t
,
661 &dev
->pkeys
.pkey_port_list
[slave
],
664 mport
= container_of(p
, struct mlx4_port
, kobj
);
665 sysfs_remove_group(p
, &mport
->pkey_group
);
666 sysfs_remove_group(p
, &mport
->gid_group
);
669 kobject_put(dev
->dev_ports_parent
[slave
]);
672 kobject_put(dev
->pkeys
.device_parent
[slave
]);
673 /* extra put for the device_parent create_and_add */
674 kobject_put(dev
->pkeys
.device_parent
[slave
]);
677 kobject_put(dev
->iov_parent
);
681 static int register_pkey_tree(struct mlx4_ib_dev
*device
)
685 if (!mlx4_is_master(device
->dev
))
688 for (i
= 0; i
<= device
->dev
->num_vfs
; ++i
)
689 register_one_pkey_tree(device
, i
);
694 static void unregister_pkey_tree(struct mlx4_ib_dev
*device
)
697 struct kobject
*p
, *t
;
698 struct mlx4_port
*port
;
700 if (!mlx4_is_master(device
->dev
))
703 for (slave
= device
->dev
->num_vfs
; slave
>= 0; --slave
) {
704 list_for_each_entry_safe(p
, t
,
705 &device
->pkeys
.pkey_port_list
[slave
],
708 port
= container_of(p
, struct mlx4_port
, kobj
);
709 sysfs_remove_group(p
, &port
->pkey_group
);
710 sysfs_remove_group(p
, &port
->gid_group
);
712 kobject_put(device
->dev_ports_parent
[slave
]);
714 kobject_put(device
->dev_ports_parent
[slave
]);
715 kobject_put(device
->pkeys
.device_parent
[slave
]);
716 kobject_put(device
->pkeys
.device_parent
[slave
]);
717 kobject_put(device
->iov_parent
);
721 int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev
*dev
)
726 if (!mlx4_is_master(dev
->dev
))
730 kobject_create_and_add("iov",
731 kobject_get(dev
->ib_dev
.ports_parent
->parent
));
732 if (!dev
->iov_parent
) {
737 kobject_create_and_add("ports",
738 kobject_get(dev
->iov_parent
));
739 if (!dev
->ports_parent
) {
744 for (i
= 1; i
<= dev
->ib_dev
.phys_port_cnt
; ++i
) {
745 ret
= add_port_entries(dev
, i
);
747 goto err_add_entries
;
750 ret
= register_pkey_tree(dev
);
752 goto err_add_entries
;
756 kobject_put(dev
->ports_parent
);
759 kobject_put(dev
->iov_parent
);
761 kobject_put(dev
->ib_dev
.ports_parent
->parent
);
762 pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret
);
766 static void unregister_alias_guid_tree(struct mlx4_ib_dev
*device
)
768 struct mlx4_ib_iov_port
*p
;
771 if (!mlx4_is_master(device
->dev
))
774 for (i
= 0; i
< device
->dev
->caps
.num_ports
; i
++) {
775 p
= &device
->iov_ports
[i
];
776 kobject_put(p
->admin_alias_parent
);
777 kobject_put(p
->gids_parent
);
778 kobject_put(p
->pkeys_parent
);
779 kobject_put(p
->mcgs_parent
);
780 kobject_put(p
->cur_port
);
781 kobject_put(p
->cur_port
);
782 kobject_put(p
->cur_port
);
783 kobject_put(p
->cur_port
);
784 kobject_put(p
->cur_port
);
785 kobject_put(p
->dev
->ports_parent
);
790 void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev
*device
)
792 unregister_alias_guid_tree(device
);
793 unregister_pkey_tree(device
);
794 kobject_put(device
->ports_parent
);
795 kobject_put(device
->iov_parent
);
796 kobject_put(device
->iov_parent
);
797 kobject_put(device
->ib_dev
.ports_parent
->parent
);