Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions drivers/genz/genz-blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,7 @@ static int genz_blk_probe(struct genz_dev *zdev,
UUID_IS_FAM, GFP_KERNEL);
if (ret < 0)
goto out; /* Revisit: undo bstate */
for (zres = genz_get_first_resource(zdev); zres != NULL;
zres = genz_get_next_resource(zdev, zres)) {
genz_for_each_resource(zres, zdev) {
if (genz_is_data_resource(zres)) {
ret = genz_bdev_probe(bstate, zres);
/* Revisit: error handling */
Expand Down
8 changes: 4 additions & 4 deletions drivers/genz/genz-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,19 +1290,19 @@ int genz_bridge_create_control_files(struct genz_bridge_dev *zbdev)
return -EINVAL;
}
f = zbdev->fabric;
s = genz_find_subnet(sid, f);
s = genz_add_subnet(sid, f);
if (s == NULL) {
pr_debug("genz_find_subnet failed\n");
pr_debug("genz_add_subnet failed\n");
return -ENOMEM;
}
ret = genz_control_read_cid0(zdev, &cid);
if (ret) {
pr_debug("couldn't read cid for bridge\n");
return -EINVAL;
}
zcomp = genz_find_component(s, cid);
zcomp = genz_add_component(s, cid);
if (zcomp == NULL) {
pr_debug("genz_find_component failed\n");
pr_debug("genz_add_component failed\n");
return -ENOMEM;
}

Expand Down
8 changes: 4 additions & 4 deletions drivers/genz/genz-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,9 @@ static int initialize_zbdev(struct genz_bridge_dev *zbdev,
pr_debug("genz_control_read_sid returned %d\n", ret);
goto error;
}
s = genz_find_subnet(sid, f);
s = genz_add_subnet(sid, f);
if (s == NULL) {
pr_debug("%s: genz_find_subnet failed\n", __func__);
pr_debug("%s: genz_add_subnet failed\n", __func__);
ret = -ENOMEM;
goto error;
}
Expand All @@ -281,9 +281,9 @@ static int initialize_zbdev(struct genz_bridge_dev *zbdev,
pr_debug("genz_control_read_cid returned %d\n", ret);
goto error;
}
zbdev->zdev.zcomp = genz_find_component(s, cid);
zbdev->zdev.zcomp = genz_add_component(s, cid);
if (zbdev->zdev.zcomp == NULL) {
pr_debug("%s: genz_find_component failed\n", __func__);
pr_debug("%s: genz_add_component failed\n", __func__);
ret = -ENOMEM;
goto error;
}
Expand Down
126 changes: 98 additions & 28 deletions drivers/genz/genz-netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,37 +190,34 @@ static int parse_mr_list(struct genz_dev *zdev, const struct nlattr *mr_list)
GENZ_CONTROL_STR_LEN,
"control%d",
&zdev->zres_list);
if (ret)
if (ret) {
pr_debug("genz_setup_zres control failed with %d\n", ret);
goto error;
}

}
else if (mem_type == GENZ_DATA) {
} else if (mem_type == GENZ_DATA) {
ret = genz_setup_zres(zres, zdev, GENZ_DATA,
(zres->zres.res.flags & ~IORESOURCE_GENZ_CONTROL),
GENZ_DATA_STR_LEN,
"data%d",
&zdev->zres_list);
if (ret)
if (ret) {
pr_debug("genz_setup_zres data failed with %d\n", ret);
goto error;
}
ret = genz_create_attr(zdev, zres);
if (ret) {
pr_debug("genz_create_attr failed with %d\n", ret);
}
} else {
pr_debug("invalid memory region mem_type %d\n", mem_type);
goto error;
}
/* Revisit: how to get the parent resource?
ret = insert_resource(&zres->res, &zdev->parent_res);
if (ret < 0) {
pr_debug("insert_resource failed with %d\n", ret);
}
*/
/* Add this resource to the genz_dev's list */
list_add_tail(&zres->zres_node, &zdev->zres_list);
}
pr_debug("\t\t\tMR_START: 0x%llx\n\t\t\t\tMR_LENGTH: %lld\n\t\t\t\tMR_TYPE: %s\n\t\t\t\tRO_RKEY: 0x%x\n\t\t\t\tRW_KREY 0x%x\n", mem_start, mem_len, (mem_type == GENZ_DATA ? "DATA":"CONTROL"), ro_rkey, rw_rkey);
}
pr_debug("\t\tend of Memory Region List\n");
return ret;
error:
pr_debug("\t\tparse_mr_list failed with %d\n", ret);
return ret;
}

Expand Down Expand Up @@ -252,7 +249,8 @@ static int parse_resource_list(const struct nlattr *resource_list,
zdev = genz_alloc_dev(fabric);
if (!zdev) {
/* Revisit: clean up fabric? */
return -ENOMEM;
ret = -ENOMEM;
goto err;
}
zdev->zcomp = zcomp;

Expand All @@ -262,6 +260,7 @@ static int parse_resource_list(const struct nlattr *resource_list,
if (ret < 0) {
pr_debug("nla_parse_nested of UUID list returned %d\n",
ret);
goto err;
}
if (u_attrs[GENZ_A_U_CLASS_UUID]) {
uint8_t *uuid;
Expand All @@ -284,7 +283,7 @@ static int parse_resource_list(const struct nlattr *resource_list,
zdev->class = nla_get_u16(u_attrs[GENZ_A_U_CLASS]);
pr_debug("\t\tClass = %d\n",
(uint32_t) zdev->class);
if (zdev->class < genz_hardware_classes_nelems) {
if (zdev->class > 0 && zdev->class < genz_hardware_classes_nelems) {
condensed_class =
genz_hardware_classes[zdev->class].value;
condensed_name =
Expand All @@ -302,23 +301,40 @@ static int parse_resource_list(const struct nlattr *resource_list,
dev_set_name(&zdev->dev, "%s%d", condensed_name,
zdev->zcomp->resource_count[condensed_class]++);
}
genz_device_initialize(zdev);
if (u_attrs[GENZ_A_U_MRL]) {
ret = parse_mr_list(zdev, u_attrs[GENZ_A_U_MRL]);
if (ret) {
pr_debug("\tparse of MRL failed\n");
goto err;
}
}
ret = genz_device_add(zdev);
/*
* The device add triggers the driver bind/probe. All of the
* resources must be in place for the driver probe. The
* sysfs files are created after the new device is added.
*/
ret = device_add(&zdev->dev);
if (ret) {
pr_debug("\tgenz_device_add failed with %d\n", ret);
pr_debug("device_add failed with %d\n", ret);
goto err;
}
ret = genz_create_uuid_file(zdev);
if (ret) {
pr_debug("\tgenz_create_uuid_file failed with %d\n", ret);
goto err;
}
ret = genz_create_attrs(zdev);
if (ret) {
pr_debug("\tgenz_create_attrs failed with %d\n", ret);
goto err;
}
}
pr_debug("\tend of RESOURCE_LIST\n");
return ret;
err:
/* Revisit: cleanup */
return ret;
}

/* Netlink Generic Handler */
Expand Down Expand Up @@ -385,14 +401,14 @@ static int genz_add_os_component(struct sk_buff *skb, struct genl_info *info)
pr_debug("GCID is invalid.\n");
return -EINVAL;
}
s = genz_find_subnet(genz_get_sid(gcid), f);
s = genz_add_subnet(genz_get_sid(gcid), f);
if (s == NULL) {
pr_debug("genz_find_subnet failed\n");
pr_debug("genz_add_subnet failed\n");
return -ENOMEM;
}
zcomp = genz_find_component(s, genz_get_cid(gcid));
zcomp = genz_add_component(s, genz_get_cid(gcid));
if (zcomp == NULL) {
pr_debug("genz_find_component failed\n");
pr_debug("genz_add_component failed\n");
return -ENOMEM;
}
/*
Expand All @@ -412,7 +428,7 @@ static int genz_add_os_component(struct sk_buff *skb, struct genl_info *info)
ret = -EINVAL;
goto err;
}
if (zcomp->cclass >= genz_hardware_classes_nelems) {
if (zcomp->cclass <= 0 || zcomp->cclass >= genz_hardware_classes_nelems) {
pr_debug("CCLASS invalid\n");
ret = -EINVAL;
goto err;
Expand Down Expand Up @@ -463,11 +479,65 @@ static int genz_add_os_component(struct sk_buff *skb, struct genl_info *info)

static int genz_remove_os_component(struct sk_buff *skb, struct genl_info *info)
{
/*
* message handling code goes here; return 0 on success,
* negative value on failure.
*/
return 0;
int ret = 0;
uint32_t gcid;
struct genz_fabric *f;
struct genz_subnet *s;
struct genz_component *zcomp = NULL;
struct uuid_tracker *uu;
uuid_t mgr_uuid;

pr_debug("genz_remove_os_component\n");
if (info->attrs[GENZ_A_MGR_UUID]) {
uint8_t * uuid_str;

uuid_str = nla_data(info->attrs[GENZ_A_MGR_UUID]);
bytes_to_uuid(&mgr_uuid, uuid_str);
pr_debug("\tMGR_UUID: %pUb\n", &mgr_uuid);
} else {
pr_debug("missing required MGR_UUID\n");
ret = -EINVAL;
goto err;
}
uu = genz_uuid_search(&mgr_uuid);
if (!uu) {
pr_debug("did not find matching MGR_UUID\n");
goto err;
}
f = uu->fabric->fabric;
if (info->attrs[GENZ_A_GCID]) {
gcid = nla_get_u32(info->attrs[GENZ_A_GCID]);
pr_debug("\tGCID: %d ", gcid);
} else {
pr_debug("missing required GCID\n");
ret = -EINVAL;
goto mgr_uuid;
}
/* validate the GCID */
if (gcid > MAX_GCID) {
pr_debug("GCID is invalid.\n");
ret = -EINVAL;
goto mgr_uuid;
}
s = genz_lookup_subnet(genz_get_sid(gcid), f);
if (s == NULL) {
pr_debug("genz_lookup_subnet failed\n");
ret = -EINVAL;
goto mgr_uuid;
}
zcomp = genz_lookup_component(s, genz_get_cid(gcid));
if (zcomp == NULL) {
pr_debug("genz_lookup_component failed\n");
ret = -EINVAL;
goto mgr_uuid;
}
/* remove the component */
device_unregister(&zcomp->dev);
mgr_uuid:
/* genz_uuid_search takes a refcount. decrement it here */
genz_uuid_remove(uu);
err:
return ret;
}

static int genz_symlink_os_component(struct sk_buff *skb, struct genl_info *info)
Expand Down
46 changes: 36 additions & 10 deletions drivers/genz/genz-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,11 @@ static int genz_init_subnet(struct genz_subnet *s,
return ret;
}

struct genz_subnet *genz_find_subnet(uint32_t sid, struct genz_fabric *f)
struct genz_subnet *genz_lookup_subnet(uint32_t sid, struct genz_fabric *f)
{
struct genz_subnet *s, *found = NULL;
int ret = 0;
unsigned long flags;

pr_debug( "in %s\n", __func__);

spin_lock_irqsave(&f->subnets_lock, flags);
list_for_each_entry(s, &f->subnets, node) {
pr_debug("subnets list genz_subnet %px\n", s);
Expand All @@ -379,6 +376,20 @@ struct genz_subnet *genz_find_subnet(uint32_t sid, struct genz_fabric *f)
}
}
spin_unlock_irqrestore(&f->subnets_lock, flags);

return found;
}

struct genz_subnet *genz_add_subnet(uint32_t sid, struct genz_fabric *f)
{
struct genz_subnet *found = NULL;
int ret = 0;
unsigned long flags;

pr_debug( "in %s\n", __func__);

found = genz_lookup_subnet(sid, f);

if (!found) {
pr_debug( "sid %d is not in the subnets list yet\n", sid);
/* Allocate a new genz_subnet and add to list */
Expand Down Expand Up @@ -534,11 +545,10 @@ void print_components(struct genz_fabric *f)

}

struct genz_component *genz_find_component(struct genz_subnet *s,
struct genz_component *genz_lookup_component(struct genz_subnet *s,
uint32_t cid)
{
struct genz_component *c, *found = NULL;
int ret = 0;
unsigned long flags;

spin_lock_irqsave(&s->fabric->components_lock, flags);
Expand All @@ -549,6 +559,18 @@ struct genz_component *genz_find_component(struct genz_subnet *s,
}
}
spin_unlock_irqrestore(&s->fabric->components_lock, flags);
return found;
}

struct genz_component *genz_add_component(struct genz_subnet *s,
uint32_t cid)
{
struct genz_component *found = NULL;
int ret = 0;
unsigned long flags;

found = genz_lookup_component(s, cid);

if (!found) {
pr_debug( "cid %d is not in the components list yet\n", cid);
/* Allocate a new genz_component and add to list */
Expand Down Expand Up @@ -654,19 +676,23 @@ struct genz_dev *genz_alloc_dev(struct genz_fabric *fabric)
return zdev;
}

int genz_device_add(struct genz_dev *zdev)
void genz_device_initialize(struct genz_dev *zdev)
{
int ret;

zdev->dev.bus = &genz_bus_type;
zdev->dev.parent = &zdev->zcomp->dev;
zdev->dev.release = genz_release_dev;
zdev->zbdev = genz_zdev_bridge(zdev);
if (zdev->zbdev == NULL) {
pr_debug("genz_device_add failed to find a bridge\n");
pr_debug("genz_device_initialize failed to find a bridge\n");
}
device_initialize(&zdev->dev);
}

int genz_device_add(struct genz_dev *zdev)
{
int ret = 0;

genz_device_initialize(zdev);
ret = device_add(&zdev->dev);
if (ret)
pr_debug("device_add failed with %d\n", ret);
Expand Down
11 changes: 8 additions & 3 deletions drivers/genz/genz-probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,19 @@
struct genz_fabric *genz_find_fabric(uint32_t fabric_num);
struct genz_fabric * genz_dev_to_fabric(struct device *dev);
void genz_free_fabric(struct device *dev);
struct genz_component *genz_find_component(struct genz_subnet *s, uint32_t cid);
struct genz_component *genz_lookup_component(struct genz_subnet *s,
uint32_t cid);
struct genz_component *genz_add_component(struct genz_subnet *s, uint32_t cid);
struct genz_component *genz_alloc_component(void);
int genz_init_component(struct genz_component *zcomp, struct genz_subnet *s, uint32_t cid);
int genz_init_component(struct genz_component *zcomp, struct genz_subnet *s,
uint32_t cid);
void genz_free_component(struct kref *kref);
struct genz_dev *genz_alloc_dev(struct genz_fabric *fabric);
int genz_init_dev(struct genz_dev *zdev, struct genz_fabric *fabric);
void genz_device_initialize(struct genz_dev *zdev);
int genz_device_add(struct genz_dev *zdev);
struct genz_subnet *genz_find_subnet(uint32_t sid, struct genz_fabric *f);
struct genz_subnet *genz_lookup_subnet(uint32_t sid, struct genz_fabric *f);
struct genz_subnet *genz_add_subnet(uint32_t sid, struct genz_fabric *f);
int genz_device_probe(struct device *dev);
const struct genz_device_id *genz_match_device(struct genz_driver *zdrv,
struct genz_dev *zdev);
Expand Down
Loading