From: Dmitry Torokhov <dtor_core@ameritech.net>
To: Kay Sievers <kay.sievers@vrfy.org>
Cc: Greg KH <gregkh@suse.de>,
linux-kernel@vger.kernel.org, Vojtech Pavlik <vojtech@suse.cz>,
Hannes Reinecke <hare@suse.de>,
Patrick Mochel <mochel@digitalimplant.org>,
airlied@linux.ie
Subject: Re: [RFC] subclasses in sysfs to solve world peace
Date: Fri, 16 Sep 2005 02:21:53 -0500 [thread overview]
Message-ID: <200509160221.54587.dtor_core@ameritech.net> (raw)
In-Reply-To: <20050916024351.GC13486@vrfy.org>
> >
> > No, like your first picture, except 'interfaces/mice' will be a directory,
> > not a symlink, since it does not have class_device parent. I should have
> > said "Otherwise it gets added into _its_ class directory".
>
Ok, this is _very_ raw and I am creating double symlinks somehow, but still
it shows it can be done:
[dtor@core ~]$ tree /sys/class/input/
/sys/class/input/
|-- devices
| |-- input0
| | |-- capabilities
| | | |-- abs
| | | |-- ev
| | | |-- ff
| | | |-- key
| | | |-- led
| | | |-- msc
| | | |-- rel
| | | |-- snd
| | | `-- sw
| | |-- device -> ../../../../devices/platform/i8042/serio1
| | |-- event0
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input0
| | |-- event0
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input0
| | |-- id
| | | |-- bustype
| | | |-- product
| | | |-- vendor
| | | `-- version
| | |-- name
| | |-- phys
| | `-- uniq
| |-- input1
| | |-- capabilities
| | | |-- abs
| | | |-- ev
| | | |-- ff
| | | |-- key
| | | |-- led
| | | |-- msc
| | | |-- rel
| | | |-- snd
| | | `-- sw
| | |-- device -> ../../../../devices/platform/i8042/serio0
| | |-- event1
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input1
| | |-- event1
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input1
| | |-- id
| | | |-- bustype
| | | |-- product
| | | |-- vendor
| | | `-- version
| | |-- mouse0
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input1
| | |-- mouse0
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input1
| | |-- name
| | |-- phys
| | |-- ts0
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input1
| | |-- ts0
| | | |-- dev
| | | `-- device -> ../../../../../class/input/devices/input1
| | `-- uniq
| `-- input2
| |-- capabilities
| | |-- abs
| | |-- ev
| | |-- ff
| | |-- key
| | |-- led
| | |-- msc
| | |-- rel
| | |-- snd
| | `-- sw
| |-- device -> ../../../../devices/platform/i8042/serio0/serio2
| |-- event2
| | |-- dev
| | `-- device -> ../../../../../class/input/devices/input2
| |-- event2
| | |-- dev
| | `-- device -> ../../../../../class/input/devices/input2
| |-- id
| | |-- bustype
| | |-- product
| | |-- vendor
| | `-- version
| |-- mouse1
| | |-- dev
| | `-- device -> ../../../../../class/input/devices/input2
| |-- mouse1
| | |-- dev
| | `-- device -> ../../../../../class/input/devices/input2
| |-- name
| |-- phys
| |-- ts1
| | |-- dev
| | `-- device -> ../../../../../class/input/devices/input2
| |-- ts1
| | |-- dev
| | `-- device -> ../../../../../class/input/devices/input2
| `-- uniq
`-- interfaces
|-- event0 -> ../../../class/input/devices/input0/event0
|-- event1 -> ../../../class/input/devices/input1/event1
|-- event2 -> ../../../class/input/devices/input2/event2
|-- mice
| `-- dev
|-- mouse0 -> ../../../class/input/devices/input1/mouse0
|-- mouse1 -> ../../../class/input/devices/input2/mouse1
|-- ts0 -> ../../../class/input/devices/input1/ts0
`-- ts1 -> ../../../class/input/devices/input2/ts1
--
Dmitry
Subject: XXX
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
drivers/base/class.c | 81 +++++++++++++++++++++++++++++++++++--------------
drivers/input/input.c | 6 +++
include/linux/device.h | 5 ++-
3 files changed, 67 insertions(+), 25 deletions(-)
Index: work/drivers/base/class.c
===================================================================
--- work.orig/drivers/base/class.c
+++ work/drivers/base/class.c
@@ -485,7 +485,7 @@ static char *make_class_name(struct clas
int class_device_add(struct class_device *class_dev)
{
- struct class * parent = NULL;
+ struct class * class = NULL;
struct class_interface * class_intf;
char *class_name = NULL;
int error;
@@ -499,15 +499,18 @@ int class_device_add(struct class_device
goto register_done;
}
- parent = class_get(class_dev->class);
+ class = class_get(class_dev->class);
pr_debug("CLASS: registering class device: ID = '%s'\n",
class_dev->class_id);
/* first, register with generic layer. */
kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
- if (parent)
- class_dev->kobj.parent = &parent->subsys.kset.kobj;
+
+ if (is_a_class_device(class_dev->parent))
+ class_dev->kobj.parent = class_dev->parent;
+ else if (class)
+ class_dev->kobj.parent = &class->subsys.kset.kobj;
if ((error = kobject_add(&class_dev->kobj)))
goto register_done;
@@ -524,7 +527,7 @@ int class_device_add(struct class_device
attr->attr.name = "dev";
attr->attr.mode = S_IRUGO;
- attr->attr.owner = parent->owner;
+ attr->attr.owner = class ? class->owner : NULL;
attr->show = show_dev;
attr->store = NULL;
class_device_create_file(class_dev, attr);
@@ -532,31 +535,45 @@ int class_device_add(struct class_device
}
class_device_add_attrs(class_dev);
+
+ /* this will go away */
if (class_dev->dev) {
class_name = make_class_name(class_dev);
- sysfs_create_link(&class_dev->kobj,
- &class_dev->dev->kobj, "device");
+ sysfs_create_link(&class_dev->kobj, &class_dev->dev->kobj,
+ "device");
sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
class_name);
+ kfree(class_name);
+ } else if (class_dev->parent) {
+ class_name = make_class_name(class_dev);
+ sysfs_create_link(&class_dev->kobj, class_dev->parent,
+ "device");
+ sysfs_create_link(class_dev->parent, &class_dev->kobj,
+ is_a_class_device(class_dev->parent) ?
+ class_dev->class_id : class_name);
+ kfree(class_name);
}
+ if (class && is_a_class_device(class_dev->parent))
+ sysfs_create_link(&class->subsys.kset.kobj, &class_dev->kobj,
+ class_dev->class_id);
+
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */
- if (parent) {
- down(&parent->sem);
- list_add_tail(&class_dev->node, &parent->children);
- list_for_each_entry(class_intf, &parent->interfaces, node)
+ if (class) {
+ down(&class->sem);
+ list_add_tail(&class_dev->node, &class->children);
+ list_for_each_entry(class_intf, &class->interfaces, node)
if (class_intf->add)
class_intf->add(class_dev, class_intf);
- up(&parent->sem);
+ up(&class->sem);
}
register_done:
- if (error && parent)
- class_put(parent);
+ if (error && class)
+ class_put(class);
class_device_put(class_dev);
- kfree(class_name);
return error;
}
@@ -619,34 +636,48 @@ error:
void class_device_del(struct class_device *class_dev)
{
- struct class * parent = class_dev->class;
+ struct class * class = class_dev->class;
struct class_interface * class_intf;
char *class_name = NULL;
- if (parent) {
- down(&parent->sem);
+ if (class) {
+ down(&class->sem);
list_del_init(&class_dev->node);
- list_for_each_entry(class_intf, &parent->interfaces, node)
+ list_for_each_entry(class_intf, &class->interfaces, node)
if (class_intf->remove)
class_intf->remove(class_dev, class_intf);
- up(&parent->sem);
+ up(&class->sem);
+ }
+
+ if (class && is_a_class_device(class_dev->parent))
+ sysfs_remove_link(&class->subsys.kset.kobj, class_dev->class_id);
+
+ if (class_dev->parent) {
+ class_name = make_class_name(class_dev);
+ sysfs_remove_link(&class_dev->kobj, "device");
+ sysfs_remove_link(class_dev->parent,
+ is_a_class_device(class_dev->parent) ?
+ class_dev->class_id : class_name);
+ kfree(class_name);
}
if (class_dev->dev) {
class_name = make_class_name(class_dev);
sysfs_remove_link(&class_dev->kobj, "device");
sysfs_remove_link(&class_dev->dev->kobj, class_name);
+ kfree(class_name);
}
+
if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr);
+
class_device_remove_attrs(class_dev);
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj);
- if (parent)
- class_put(parent);
- kfree(class_name);
+ if (class)
+ class_put(class);
}
void class_device_unregister(struct class_device *class_dev)
@@ -715,6 +746,10 @@ void class_device_put(struct class_devic
kobject_put(&class_dev->kobj);
}
+int is_a_class_device(struct kobject *kobj)
+{
+ return kobj && get_ktype(kobj) == &ktype_class_device;
+}
int class_interface_register(struct class_interface *class_intf)
{
Index: work/include/linux/device.h
===================================================================
--- work.orig/include/linux/device.h
+++ work/include/linux/device.h
@@ -199,7 +199,8 @@ struct class_device {
struct class * class; /* required */
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct class_device_attribute *devt_attr;
- struct device * dev; /* not necessary, but nice to have */
+ struct device * dev; /* not necessary, but nice to have (going away) */
+ struct kobject * parent; /* either device or class_device */
void * class_data; /* class-specific data */
char class_id[BUS_ID_SIZE]; /* unique to this class */
@@ -229,6 +230,8 @@ extern int class_device_rename(struct cl
extern struct class_device * class_device_get(struct class_device *);
extern void class_device_put(struct class_device *);
+extern int is_a_class_device(struct kobject *);
+
struct class_device_attribute {
struct attribute attr;
ssize_t (*show)(struct class_device *, char * buf);
Index: work/drivers/input/input.c
===================================================================
--- work.orig/drivers/input/input.c
+++ work/drivers/input/input.c
@@ -948,18 +948,22 @@ int input_create_interface_device(struct
dev->devt = devt;
dev->class = &input_interface_class;
+ if (handle->dev)
+ dev->parent = &handle->dev->cdev.kobj;
strlcpy(dev->class_id, handle->name, BUS_ID_SIZE);
+
error = class_device_register(dev);
if (error)
return error;
+/*
if (handle->dev) {
sysfs_create_link(&dev->kobj, &handle->dev->cdev.kobj, "device");
sysfs_create_link(&handle->dev->cdev.kobj, &dev->kobj,
kobject_name(&dev->kobj));
}
-
+*/
handle->intf_dev = dev;
__module_get(THIS_MODULE);
next prev parent reply other threads:[~2005-09-16 7:22 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-16 0:20 [RFC] subclasses in sysfs to solve world peace Greg KH
2005-09-16 0:58 ` Dmitry Torokhov
2005-09-16 1:46 ` Kay Sievers
2005-09-16 1:58 ` Dmitry Torokhov
2005-09-16 21:54 ` Greg KH
2005-09-16 1:04 ` Kay Sievers
2005-09-16 1:23 ` Dmitry Torokhov
2005-09-16 1:54 ` Kay Sievers
2005-09-16 2:03 ` Dmitry Torokhov
2005-09-16 2:14 ` Kay Sievers
2005-09-16 2:36 ` Dmitry Torokhov
2005-09-16 2:43 ` Kay Sievers
2005-09-16 3:10 ` Dmitry Torokhov
2005-09-16 7:21 ` Dmitry Torokhov [this message]
2005-09-16 21:48 ` Greg KH
2005-09-16 22:55 ` Dmitry Torokhov
2005-09-16 8:02 ` Vojtech Pavlik
2005-09-16 15:44 ` Dmitry Torokhov
2005-09-16 21:50 ` Greg KH
2005-09-16 22:56 ` Dmitry Torokhov
2005-09-17 0:48 ` Dave Airlie
2005-09-16 21:49 ` Greg KH
2005-09-16 7:59 ` Vojtech Pavlik
2005-09-16 21:55 ` Greg KH
2005-09-16 22:45 ` Dmitry Torokhov
2005-09-17 0:20 ` Antonino A. Daplas
-- strict thread matches above, loose matches on Subject: below --
2005-09-16 1:45 David Lang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200509160221.54587.dtor_core@ameritech.net \
--to=dtor_core@ameritech.net \
--cc=airlied@linux.ie \
--cc=gregkh@suse.de \
--cc=hare@suse.de \
--cc=kay.sievers@vrfy.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mochel@digitalimplant.org \
--cc=vojtech@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.