RDMA/core: Expose the ib port sysfs attribute machinery
Other things outside the core code are creating attributes against the port. This patch exposes the basic machinery to do this. The ib_port_attribute type allows creating groups of attributes attatched to the port and comes with the usual machinery to do this. Link: https://lore.kernel.org/r/5c4aeae57f6fa7c59a1d6d1c5506069516ae9bbf.1623427137.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
d89eb509aa
commit
054239f45c
|
@ -44,24 +44,10 @@
|
|||
#include <rdma/ib_pma.h>
|
||||
#include <rdma/ib_cache.h>
|
||||
#include <rdma/rdma_counter.h>
|
||||
|
||||
struct ib_port;
|
||||
|
||||
struct port_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct ib_port *, struct port_attribute *, char *buf);
|
||||
ssize_t (*store)(struct ib_port *, struct port_attribute *,
|
||||
const char *buf, size_t count);
|
||||
};
|
||||
|
||||
#define PORT_ATTR(_name, _mode, _show, _store) \
|
||||
struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
||||
|
||||
#define PORT_ATTR_RO(_name) \
|
||||
struct port_attribute port_attr_##_name = __ATTR_RO(_name)
|
||||
#include <rdma/ib_sysfs.h>
|
||||
|
||||
struct port_table_attribute {
|
||||
struct port_attribute attr;
|
||||
struct ib_port_attribute attr;
|
||||
char name[8];
|
||||
int index;
|
||||
__be16 attr_id;
|
||||
|
@ -97,7 +83,7 @@ struct hw_stats_device_attribute {
|
|||
};
|
||||
|
||||
struct hw_stats_port_attribute {
|
||||
struct port_attribute attr;
|
||||
struct ib_port_attribute attr;
|
||||
ssize_t (*show)(struct ib_device *ibdev, struct rdma_hw_stats *stats,
|
||||
unsigned int index, unsigned int port_num, char *buf);
|
||||
ssize_t (*store)(struct ib_device *ibdev, struct rdma_hw_stats *stats,
|
||||
|
@ -119,29 +105,55 @@ struct hw_stats_port_data {
|
|||
static ssize_t port_attr_show(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf)
|
||||
{
|
||||
struct port_attribute *port_attr =
|
||||
container_of(attr, struct port_attribute, attr);
|
||||
struct ib_port_attribute *port_attr =
|
||||
container_of(attr, struct ib_port_attribute, attr);
|
||||
struct ib_port *p = container_of(kobj, struct ib_port, kobj);
|
||||
|
||||
if (!port_attr->show)
|
||||
return -EIO;
|
||||
|
||||
return port_attr->show(p, port_attr, buf);
|
||||
return port_attr->show(p->ibdev, p->port_num, port_attr, buf);
|
||||
}
|
||||
|
||||
static ssize_t port_attr_store(struct kobject *kobj,
|
||||
struct attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct port_attribute *port_attr =
|
||||
container_of(attr, struct port_attribute, attr);
|
||||
struct ib_port_attribute *port_attr =
|
||||
container_of(attr, struct ib_port_attribute, attr);
|
||||
struct ib_port *p = container_of(kobj, struct ib_port, kobj);
|
||||
|
||||
if (!port_attr->store)
|
||||
return -EIO;
|
||||
return port_attr->store(p, port_attr, buf, count);
|
||||
return port_attr->store(p->ibdev, p->port_num, port_attr, buf, count);
|
||||
}
|
||||
|
||||
int ib_port_sysfs_create_groups(struct ib_device *ibdev, u32 port_num,
|
||||
const struct attribute_group **groups)
|
||||
{
|
||||
return sysfs_create_groups(&ibdev->port_data[port_num].sysfs->kobj,
|
||||
groups);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ib_port_sysfs_create_groups);
|
||||
|
||||
void ib_port_sysfs_remove_groups(struct ib_device *ibdev, u32 port_num,
|
||||
const struct attribute_group **groups)
|
||||
{
|
||||
return sysfs_remove_groups(&ibdev->port_data[port_num].sysfs->kobj,
|
||||
groups);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ib_port_sysfs_remove_groups);
|
||||
|
||||
struct ib_device *ib_port_sysfs_get_ibdev_kobj(struct kobject *kobj,
|
||||
u32 *port_num)
|
||||
{
|
||||
struct ib_port *port = container_of(kobj, struct ib_port, kobj);
|
||||
|
||||
*port_num = port->port_num;
|
||||
return port->ibdev;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_port_sysfs_get_ibdev_kobj);
|
||||
|
||||
static const struct sysfs_ops port_sysfs_ops = {
|
||||
.show = port_attr_show,
|
||||
.store = port_attr_store
|
||||
|
@ -171,25 +183,27 @@ static ssize_t hw_stat_device_store(struct device *dev,
|
|||
count);
|
||||
}
|
||||
|
||||
static ssize_t hw_stat_port_show(struct ib_port *port,
|
||||
struct port_attribute *attr, char *buf)
|
||||
static ssize_t hw_stat_port_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr, char *buf)
|
||||
{
|
||||
struct hw_stats_port_attribute *stat_attr =
|
||||
container_of(attr, struct hw_stats_port_attribute, attr);
|
||||
struct ib_port *port = ibdev->port_data[port_num].sysfs;
|
||||
|
||||
return stat_attr->show(port->ibdev, port->hw_stats_data->stats,
|
||||
return stat_attr->show(ibdev, port->hw_stats_data->stats,
|
||||
stat_attr - port->hw_stats_data->attrs,
|
||||
port->port_num, buf);
|
||||
}
|
||||
|
||||
static ssize_t hw_stat_port_store(struct ib_port *port,
|
||||
struct port_attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
static ssize_t hw_stat_port_store(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct hw_stats_port_attribute *stat_attr =
|
||||
container_of(attr, struct hw_stats_port_attribute, attr);
|
||||
struct ib_port *port = ibdev->port_data[port_num].sysfs;
|
||||
|
||||
return stat_attr->store(port->ibdev, port->hw_stats_data->stats,
|
||||
return stat_attr->store(ibdev, port->hw_stats_data->stats,
|
||||
stat_attr - port->hw_stats_data->attrs,
|
||||
port->port_num, buf, count);
|
||||
}
|
||||
|
@ -197,23 +211,23 @@ static ssize_t hw_stat_port_store(struct ib_port *port,
|
|||
static ssize_t gid_attr_show(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf)
|
||||
{
|
||||
struct port_attribute *port_attr =
|
||||
container_of(attr, struct port_attribute, attr);
|
||||
struct ib_port_attribute *port_attr =
|
||||
container_of(attr, struct ib_port_attribute, attr);
|
||||
struct ib_port *p = container_of(kobj, struct gid_attr_group,
|
||||
kobj)->port;
|
||||
|
||||
if (!port_attr->show)
|
||||
return -EIO;
|
||||
|
||||
return port_attr->show(p, port_attr, buf);
|
||||
return port_attr->show(p->ibdev, p->port_num, port_attr, buf);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops gid_attr_sysfs_ops = {
|
||||
.show = gid_attr_show
|
||||
};
|
||||
|
||||
static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t state_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
ssize_t ret;
|
||||
|
@ -227,7 +241,7 @@ static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
|
|||
[IB_PORT_ACTIVE_DEFER] = "ACTIVE_DEFER"
|
||||
};
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -238,81 +252,80 @@ static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
|
|||
"UNKNOWN");
|
||||
}
|
||||
|
||||
static ssize_t lid_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t lid_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_emit(buf, "0x%x\n", attr.lid);
|
||||
}
|
||||
|
||||
static ssize_t lid_mask_count_show(struct ib_port *p,
|
||||
struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t lid_mask_count_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_emit(buf, "%d\n", attr.lmc);
|
||||
}
|
||||
|
||||
static ssize_t sm_lid_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t sm_lid_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_emit(buf, "0x%x\n", attr.sm_lid);
|
||||
}
|
||||
|
||||
static ssize_t sm_sl_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t sm_sl_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_emit(buf, "%d\n", attr.sm_sl);
|
||||
}
|
||||
|
||||
static ssize_t cap_mask_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t cap_mask_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_emit(buf, "0x%08x\n", attr.port_cap_flags);
|
||||
}
|
||||
|
||||
static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t rate_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
char *speed = "";
|
||||
int rate; /* in deci-Gb/sec */
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -379,14 +392,14 @@ static const char *phys_state_to_str(enum ib_port_phys_state phys_state)
|
|||
return "<unknown>";
|
||||
}
|
||||
|
||||
static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t phys_state_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
struct ib_port_attr attr;
|
||||
|
||||
ssize_t ret;
|
||||
|
||||
ret = ib_query_port(p->ibdev, p->port_num, &attr);
|
||||
ret = ib_query_port(ibdev, port_num, &attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -394,12 +407,12 @@ static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
|
|||
phys_state_to_str(attr.phys_state));
|
||||
}
|
||||
|
||||
static ssize_t link_layer_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
static ssize_t link_layer_show(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *unused, char *buf)
|
||||
{
|
||||
const char *output;
|
||||
|
||||
switch (rdma_port_get_link_layer(p->ibdev, p->port_num)) {
|
||||
switch (rdma_port_get_link_layer(ibdev, port_num)) {
|
||||
case IB_LINK_LAYER_INFINIBAND:
|
||||
output = "InfiniBand";
|
||||
break;
|
||||
|
@ -414,26 +427,26 @@ static ssize_t link_layer_show(struct ib_port *p, struct port_attribute *unused,
|
|||
return sysfs_emit(buf, "%s\n", output);
|
||||
}
|
||||
|
||||
static PORT_ATTR_RO(state);
|
||||
static PORT_ATTR_RO(lid);
|
||||
static PORT_ATTR_RO(lid_mask_count);
|
||||
static PORT_ATTR_RO(sm_lid);
|
||||
static PORT_ATTR_RO(sm_sl);
|
||||
static PORT_ATTR_RO(cap_mask);
|
||||
static PORT_ATTR_RO(rate);
|
||||
static PORT_ATTR_RO(phys_state);
|
||||
static PORT_ATTR_RO(link_layer);
|
||||
static IB_PORT_ATTR_RO(state);
|
||||
static IB_PORT_ATTR_RO(lid);
|
||||
static IB_PORT_ATTR_RO(lid_mask_count);
|
||||
static IB_PORT_ATTR_RO(sm_lid);
|
||||
static IB_PORT_ATTR_RO(sm_sl);
|
||||
static IB_PORT_ATTR_RO(cap_mask);
|
||||
static IB_PORT_ATTR_RO(rate);
|
||||
static IB_PORT_ATTR_RO(phys_state);
|
||||
static IB_PORT_ATTR_RO(link_layer);
|
||||
|
||||
static struct attribute *port_default_attrs[] = {
|
||||
&port_attr_state.attr,
|
||||
&port_attr_lid.attr,
|
||||
&port_attr_lid_mask_count.attr,
|
||||
&port_attr_sm_lid.attr,
|
||||
&port_attr_sm_sl.attr,
|
||||
&port_attr_cap_mask.attr,
|
||||
&port_attr_rate.attr,
|
||||
&port_attr_phys_state.attr,
|
||||
&port_attr_link_layer.attr,
|
||||
&ib_port_attr_state.attr,
|
||||
&ib_port_attr_lid.attr,
|
||||
&ib_port_attr_lid_mask_count.attr,
|
||||
&ib_port_attr_sm_lid.attr,
|
||||
&ib_port_attr_sm_sl.attr,
|
||||
&ib_port_attr_cap_mask.attr,
|
||||
&ib_port_attr_rate.attr,
|
||||
&ib_port_attr_phys_state.attr,
|
||||
&ib_port_attr_link_layer.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -457,7 +470,8 @@ static ssize_t print_gid_type(const struct ib_gid_attr *gid_attr, char *buf)
|
|||
}
|
||||
|
||||
static ssize_t _show_port_gid_attr(
|
||||
struct ib_port *p, struct port_attribute *attr, char *buf,
|
||||
struct ib_device *ibdev, u32 port_num, struct ib_port_attribute *attr,
|
||||
char *buf,
|
||||
ssize_t (*print)(const struct ib_gid_attr *gid_attr, char *buf))
|
||||
{
|
||||
struct port_table_attribute *tab_attr =
|
||||
|
@ -465,7 +479,7 @@ static ssize_t _show_port_gid_attr(
|
|||
const struct ib_gid_attr *gid_attr;
|
||||
ssize_t ret;
|
||||
|
||||
gid_attr = rdma_get_gid_attr(p->ibdev, p->port_num, tab_attr->index);
|
||||
gid_attr = rdma_get_gid_attr(ibdev, port_num, tab_attr->index);
|
||||
if (IS_ERR(gid_attr))
|
||||
/* -EINVAL is returned for user space compatibility reasons. */
|
||||
return -EINVAL;
|
||||
|
@ -475,15 +489,15 @@ static ssize_t _show_port_gid_attr(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
|
||||
char *buf)
|
||||
static ssize_t show_port_gid(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr, char *buf)
|
||||
{
|
||||
struct port_table_attribute *tab_attr =
|
||||
container_of(attr, struct port_table_attribute, attr);
|
||||
const struct ib_gid_attr *gid_attr;
|
||||
int len;
|
||||
|
||||
gid_attr = rdma_get_gid_attr(p->ibdev, p->port_num, tab_attr->index);
|
||||
gid_attr = rdma_get_gid_attr(ibdev, port_num, tab_attr->index);
|
||||
if (IS_ERR(gid_attr)) {
|
||||
const union ib_gid zgid = {};
|
||||
|
||||
|
@ -504,28 +518,30 @@ static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t show_port_gid_attr_ndev(struct ib_port *p,
|
||||
struct port_attribute *attr, char *buf)
|
||||
static ssize_t show_port_gid_attr_ndev(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return _show_port_gid_attr(p, attr, buf, print_ndev);
|
||||
return _show_port_gid_attr(ibdev, port_num, attr, buf, print_ndev);
|
||||
}
|
||||
|
||||
static ssize_t show_port_gid_attr_gid_type(struct ib_port *p,
|
||||
struct port_attribute *attr,
|
||||
static ssize_t show_port_gid_attr_gid_type(struct ib_device *ibdev,
|
||||
u32 port_num,
|
||||
struct ib_port_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return _show_port_gid_attr(p, attr, buf, print_gid_type);
|
||||
return _show_port_gid_attr(ibdev, port_num, attr, buf, print_gid_type);
|
||||
}
|
||||
|
||||
static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
|
||||
char *buf)
|
||||
static ssize_t show_port_pkey(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr, char *buf)
|
||||
{
|
||||
struct port_table_attribute *tab_attr =
|
||||
container_of(attr, struct port_table_attribute, attr);
|
||||
u16 pkey;
|
||||
int ret;
|
||||
|
||||
ret = ib_query_pkey(p->ibdev, p->port_num, tab_attr->index, &pkey);
|
||||
ret = ib_query_pkey(ibdev, port_num, tab_attr->index, &pkey);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -594,8 +610,8 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
|
||||
char *buf)
|
||||
static ssize_t show_pma_counter(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr, char *buf)
|
||||
{
|
||||
struct port_table_attribute *tab_attr =
|
||||
container_of(attr, struct port_table_attribute, attr);
|
||||
|
@ -605,7 +621,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
|
|||
u8 data[8];
|
||||
int len;
|
||||
|
||||
ret = get_perf_mad(p->ibdev, p->port_num, tab_attr->attr_id, &data,
|
||||
ret = get_perf_mad(ibdev, port_num, tab_attr->attr_id, &data,
|
||||
40 + offset / 8, sizeof(data));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -1077,10 +1093,11 @@ struct rdma_hw_stats *ib_get_hw_stats_port(struct ib_device *ibdev,
|
|||
return ibdev->port_data[port_num].sysfs->hw_stats_data->stats;
|
||||
}
|
||||
|
||||
static int alloc_port_table_group(
|
||||
const char *name, struct attribute_group *group,
|
||||
struct port_table_attribute *attrs, size_t num,
|
||||
ssize_t (*show)(struct ib_port *, struct port_attribute *, char *buf))
|
||||
static int
|
||||
alloc_port_table_group(const char *name, struct attribute_group *group,
|
||||
struct port_table_attribute *attrs, size_t num,
|
||||
ssize_t (*show)(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *, char *buf))
|
||||
{
|
||||
struct attribute **attr_list;
|
||||
int i;
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2021 Mellanox Technologies Ltd. All rights reserved.
|
||||
*/
|
||||
#ifndef DEF_RDMA_IB_SYSFS_H
|
||||
#define DEF_RDMA_IB_SYSFS_H
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
struct ib_device;
|
||||
|
||||
struct ib_port_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr, char *buf);
|
||||
ssize_t (*store)(struct ib_device *ibdev, u32 port_num,
|
||||
struct ib_port_attribute *attr, const char *buf,
|
||||
size_t count);
|
||||
};
|
||||
|
||||
#define IB_PORT_ATTR_RW(_name) \
|
||||
struct ib_port_attribute ib_port_attr_##_name = __ATTR_RW(_name)
|
||||
|
||||
#define IB_PORT_ATTR_ADMIN_RW(_name) \
|
||||
struct ib_port_attribute ib_port_attr_##_name = \
|
||||
__ATTR_RW_MODE(_name, 0600)
|
||||
|
||||
#define IB_PORT_ATTR_RO(_name) \
|
||||
struct ib_port_attribute ib_port_attr_##_name = __ATTR_RO(_name)
|
||||
|
||||
#define IB_PORT_ATTR_WO(_name) \
|
||||
struct ib_port_attribute ib_port_attr_##_name = __ATTR_WO(_name)
|
||||
|
||||
int ib_port_sysfs_create_groups(struct ib_device *ibdev, u32 port_num,
|
||||
const struct attribute_group **groups);
|
||||
void ib_port_sysfs_remove_groups(struct ib_device *ibdev, u32 port_num,
|
||||
const struct attribute_group **groups);
|
||||
struct ib_device *ib_port_sysfs_get_ibdev_kobj(struct kobject *kobj,
|
||||
u32 *port_num);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue