Skip to content

Commit

Permalink
staging: unisys: Wire up proper device attr for bus
Browse files Browse the repository at this point in the history
This patch moves the attributes to underneath the bus device correctly.
This will help remove a bunch of cruft from the code and let the kernel
infrastructure manage the sysfs files instead of the driver.

After the move remove all the leftover code.

Signed-off-by: Don Zickus <[email protected]>
Signed-off-by: Benjamin Romer <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
dzickusrh authored and gregkh committed May 24, 2015
1 parent 03274d3 commit d181dd0
Showing 1 changed file with 55 additions and 211 deletions.
266 changes: 55 additions & 211 deletions drivers/staging/unisys/visorbus/visorbus_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,113 +606,8 @@ void unregister_channel_attributes(struct visor_device *dev)
kobject_put(&dev->kobjchannel);
dev->kobjchannel.parent = NULL;
}
/* This is actually something they forgot to put in the kernel.
* struct bus_type in the kernel SHOULD have a "busses" member, which
* should be treated similarly to the "devices" and "drivers" members.
* There SHOULD be:
* - a "businst_attribute" analogous to the existing "bus_attribute"
* - a "businst_create_file" and "businst_remove_file" analogous to the
* existing "bus_create_file" and "bus_remove_file".
* That's what I created businst.c and businst.h to do.
*
* We want to add the "busses" sub-tree in sysfs, where we will house the
* names and properties of each bus instance:
*
* /sys/bus/<bustypename>/
* version
* devices
* <devname1> --> /sys/devices/<businstancename><devname1>
* <devname2> --> /sys/devices/<businstancename><devname2>
* drivers
* <driverinstancename1>
* <driverinstance1property1>
* <driverinstance1property2>
* ...
* <driverinstancename2>
* <driverinstance2property1>
* <driverinstance2property2>
* ...
* >> busses
* >> <businstancename1>
* >> <businstance1property1>
* >> <businstance1property2>
* >> ...
* >> <businstancename2>
* >> <businstance2property1>
* >> <businstance2property2>
* >> ...
*
* I considered adding bus instance properties under
* /sys/devices/<businstancename>. But I thought there may be existing
* notions that ONLY device sub-trees should live under
* /sys/devices/<businstancename>. So I stayed out of there.
*
*/

struct businst_attribute {
struct attribute attr;
ssize_t (*show)(struct visorbus_devdata*, char *buf);
ssize_t (*store)(struct visorbus_devdata*, const char *buf,
size_t count);
};

#define to_businst_attr(_attr) \
container_of(_attr, struct businst_attribute, attr)
#define to_visorbus_devdata(obj) \
container_of(obj, struct visorbus_devdata, kobj)

static ssize_t
businst_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct businst_attribute *businst_attr = to_businst_attr(attr);
struct visorbus_devdata *bus = to_visorbus_devdata(kobj);
ssize_t ret = 0;

if (businst_attr->show)
ret = businst_attr->show(bus, buf);
return ret;
}

static ssize_t
businst_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
struct businst_attribute *businst_attr = to_businst_attr(attr);
struct visorbus_devdata *bus = to_visorbus_devdata(kobj);
ssize_t ret = 0;

if (businst_attr->store)
ret = businst_attr->store(bus, buf, count);
return ret;
}

static int
businst_create_file(struct visorbus_devdata *bus,
struct businst_attribute *attr)
{
return sysfs_create_file(&bus->kobj, &attr->attr);
}

static void
businst_remove_file(struct visorbus_devdata *bus,
struct businst_attribute *attr)
{
sysfs_remove_file(&bus->kobj, &attr->attr);
}

static const struct sysfs_ops businst_sysfs_ops = {
.show = businst_attr_show,
.store = businst_attr_store,
};

static struct kobj_type businst_kobj_type = {
.sysfs_ops = &businst_sysfs_ops
};

static struct kset businstances = { /* should actually be a member of
* bus_type */
};
container_of(obj, struct visorbus_devdata, dev)

/* BUS type attributes
*
Expand All @@ -736,31 +631,13 @@ register_bustype_attributes(void)
int rc = 0;

rc = bus_create_file(&visorbus_type, &bustype_attr_version);
if (rc < 0)
goto away;

/* Here we make up for the fact that bus_type does not yet have a
* member to keep track of multiple bus instances for a given bus
* type. This is useful for stashing properties for each bus
* instance.
*/
kobject_set_name(&businstances.kobj, "busses");
businstances.kobj.ktype = &businst_kobj_type;
businstances.kobj.parent = &visorbus_type.p->subsys.kobj;
rc = kset_register(&businstances);
if (rc < 0)
goto away;

rc = 0;
away:
return rc;
}

static void
unregister_bustype_attributes(void)
{
bus_remove_file(&visorbus_type, &bustype_attr_version);
kset_unregister(&businstances);
}

/* BUS instance attributes
Expand All @@ -774,8 +651,10 @@ unregister_bustype_attributes(void)
*
*/

static ssize_t businst_attr_partition_handle(struct visorbus_devdata *businst,
char *buf) {
static ssize_t partition_handle_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
struct visorchipset_bus_info bus_info;
int len = 0;

Expand All @@ -786,8 +665,10 @@ static ssize_t businst_attr_partition_handle(struct visorbus_devdata *businst,
return len;
}

static ssize_t businst_attr_partition_guid(struct visorbus_devdata *businst,
char *buf) {
static ssize_t partition_guid_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
struct visorchipset_bus_info bus_info;
int len = 0;

Expand All @@ -797,8 +678,10 @@ static ssize_t businst_attr_partition_guid(struct visorbus_devdata *businst,
return len;
}

static ssize_t businst_attr_partition_name(struct visorbus_devdata *businst,
char *buf) {
static ssize_t partition_name_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
struct visorchipset_bus_info bus_info;
int len = 0;

Expand All @@ -809,8 +692,10 @@ static ssize_t businst_attr_partition_name(struct visorbus_devdata *businst,
return len;
}

static ssize_t businst_attr_channel_addr(struct visorbus_devdata *businst,
char *buf) {
static ssize_t channel_addr_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
struct visorchipset_bus_info bus_info;
int len = 0;

Expand All @@ -820,8 +705,10 @@ static ssize_t businst_attr_channel_addr(struct visorbus_devdata *businst,
return len;
}

static ssize_t businst_attr_nchannel_bytes(struct visorbus_devdata *businst,
char *buf) {
static ssize_t channel_bytes_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
struct visorchipset_bus_info bus_info;
int len = 0;

Expand All @@ -831,8 +718,10 @@ static ssize_t businst_attr_nchannel_bytes(struct visorbus_devdata *businst,
return len;
}

static ssize_t businst_attr_channel_id(struct visorbus_devdata *businst,
char *buf) {
static ssize_t channel_id_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
int len = 0;

if (businst && businst->chan) {
Expand All @@ -843,8 +732,10 @@ static ssize_t businst_attr_channel_id(struct visorbus_devdata *businst,
return len;
}

static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst,
char *buf) {
static ssize_t client_bus_info_show(struct device *dev,
struct device_attribute *attr,
char *buf) {
struct visorbus_devdata *businst = to_visorbus_devdata(dev);
struct visorchipset_bus_info bus_info;
int i, x, remain = PAGE_SIZE;
unsigned long off;
Expand Down Expand Up @@ -903,79 +794,33 @@ static ssize_t businst_attr_client_bus_info(struct visorbus_devdata *businst,
return PAGE_SIZE - remain;
}

static struct businst_attribute ba_partition_handle =
__ATTR(partition_handle, S_IRUGO, businst_attr_partition_handle, NULL);
static struct businst_attribute ba_partition_guid =
__ATTR(partition_guid, S_IRUGO, businst_attr_partition_guid, NULL);
static struct businst_attribute ba_partition_name =
__ATTR(partition_name, S_IRUGO, businst_attr_partition_name, NULL);
static struct businst_attribute ba_channel_addr =
__ATTR(channel_addr, S_IRUGO, businst_attr_channel_addr, NULL);
static struct businst_attribute ba_nchannel_bytes =
__ATTR(nchannel_bytes, S_IRUGO, businst_attr_nchannel_bytes, NULL);
static struct businst_attribute ba_channel_id =
__ATTR(channel_id, S_IRUGO, businst_attr_channel_id, NULL);
static struct businst_attribute ba_client_bus_info =
__ATTR(client_bus_info, S_IRUGO, businst_attr_client_bus_info, NULL);

static int
register_businst_attributes(struct visorbus_devdata *businst)
{
int rc = 0;

businst->kobj.kset = &businstances; /* identify parent sysfs dir */
rc = kobject_init_and_add(&businst->kobj, &businst_kobj_type,
NULL, "visorbus%d", businst->devno);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_partition_handle);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_partition_guid);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_partition_name);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_channel_addr);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_nchannel_bytes);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_channel_id);
if (rc < 0)
goto away;

rc = businst_create_file(businst, &ba_client_bus_info);
if (rc < 0)
goto away;

kobject_uevent(&businst->kobj, KOBJ_ADD);
static DEVICE_ATTR_RO(partition_handle);
static DEVICE_ATTR_RO(partition_guid);
static DEVICE_ATTR_RO(partition_name);
static DEVICE_ATTR_RO(channel_addr);
static DEVICE_ATTR_RO(channel_bytes);
static DEVICE_ATTR_RO(channel_id);
static DEVICE_ATTR_RO(client_bus_info);

static struct attribute *dev_attrs[] = {
&dev_attr_partition_handle.attr,
&dev_attr_partition_guid.attr,
&dev_attr_partition_name.attr,
&dev_attr_channel_addr.attr,
&dev_attr_channel_bytes.attr,
&dev_attr_channel_id.attr,
&dev_attr_client_bus_info.attr,
NULL
};

rc = 0;
away:
return rc;
}
static struct attribute_group dev_attr_grp = {
.attrs = dev_attrs,
};

static void
unregister_businst_attributes(struct visorbus_devdata *businst)
{
businst_remove_file(businst, &ba_partition_handle);
businst_remove_file(businst, &ba_partition_guid);
businst_remove_file(businst, &ba_partition_name);
businst_remove_file(businst, &ba_channel_addr);
businst_remove_file(businst, &ba_nchannel_bytes);
businst_remove_file(businst, &ba_channel_id);
businst_remove_file(businst, &ba_client_bus_info);
kobject_put(&businst->kobj);
}
static const struct attribute_group *visorbus_groups[] = {
&dev_attr_grp,
NULL
};

/* DRIVER attributes
*
Expand Down Expand Up @@ -1646,6 +1491,7 @@ create_bus_instance(int id)
goto away;
}
dev_set_name(&devdata->dev, "visorbus%d", id);
devdata->dev.groups = visorbus_groups;
devdata->dev.release = visorbus_release_busdevice;
if (device_register(&devdata->dev) < 0) {
POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, id,
Expand Down Expand Up @@ -1692,7 +1538,6 @@ create_bus_instance(int id)
}
}
}
register_businst_attributes(devdata);
bus_count++;
list_add_tail(&devdata->list_all, &list_all_bus_instances);
if (id == 0)
Expand All @@ -1715,7 +1560,6 @@ remove_bus_instance(struct visorbus_devdata *devdata)
* successfully been able to trace thru the code to see where/how
* release() gets called. But I know it does.
*/
unregister_businst_attributes(devdata);
bus_count--;
if (devdata->chan) {
visorchannel_destroy(devdata->chan);
Expand Down

0 comments on commit d181dd0

Please sign in to comment.