Nesting class_device patches that actually work
Subsystems (21)
cover Nesting class_device patches that actually work
Ok, finally. Here's a set of _working_ patches that properly implement nesting class_device structures, and the follow-on patches to move the input subsystem to use them. Hotplug and release functions work properly now, and this will let us move /sys/block/ to use class and class_device structures soon.
The input patches are on top of almost all of Dmitry's input patches. All of them are together in one series in my public patches at:
kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
and should show up in the next -mm release.
The sysfs tree looks the same as it did last time, but now hotplug works properly for addition and removal, and we actually free the memory used :)
For those that don't remember, here's the sysfs tree on my desktop:
$ tree /sys/class/input/ -d /sys/class/input/ |-- input0 | |-- capabilities | |-- event0 | `-- id |-- input1 | |-- capabilities | |-- device -> ../../../devices/platform/i8042/serio1 | |-- event1 | | `-- device -> ../../../../devices/platform/i8042/serio1 | `-- id |-- input3 | |-- capabilities | |-- device -> ../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | |-- event2 | | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | |-- id | |-- mouse0 | | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | `-- ts0 | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 `-- mice
To answer the remaining questions from the last thread:
Q: how are you going to determine what is really a class_dev and what
isn't, as there's no way to tell.
A: Who cares? Seriously, tools like udev will watch for the "dev" file
to be able create the required device node, and it will be the one getting the hotplug event. attribute groups do not generate hotplug events, and you should not be having a file called "dev" in your attribute group anyway.
Q: why does event2, mouse0, and input3 in the above tree all have the
same "device" symlink?
A: userspace tools expect that symlink there. They do not know that if
you traverse up a directory, and look at the symlink there, that's what the subdirectory points to too. That would be a mess. And, as those different class_device structures really are all bound to that same struct device, that is the proper representation of this.
Q: How can you determine between input interfaces and input devices?
A: input devices have a "dev" file. And what really does userspace need
to know here?
Q: Wait, what about nesting struct class instead? That would work,
right?
A: No, nesting classes is not going to happen. Classes are "major"
things, and aren't related to each other (well, some are by their name only, like the different "scsi*" classes, but to the user, they are separate.)
Also, we can't emulate /sys/block with nested classes. And no, we can't change this to be /sys/class/block/partitions and /sys/class/block/devices without almost every sysfs user complaining loudly. That's not the real representation of the devices, and we need to really try to keep backward compatibility where we possibly can.
Ok, I think that covers everything.
Oh, one final thing. I really don't think that input should be a class. It looks like a "bus" and acts like a "bus" (you have different devices that have different drivers bind to them, and you want to load those drivers with the hotplug mechanism.) The only thing keeping this from being a bus is the fact that we can't bind multiple drivers to a single device these days, and I can't see a way to move this code to that model, so oh well...
thanks,
greg k-h
PATCH 1/8 Driver Core: add the ability for class_device structures to be nested
From: Greg Kroah-Hartman <[email protected]>
This patch allows struct class_device to be nested, so that another struct class_device can be the parent of a new one, instead of only having the struct class be the parent. This will allow us to (hopefully) fix up the input and video class subsystem mess.
But please people, don't go crazy and start making huge trees of class devices, you should only need 2 levels deep to get everything to work (remember to use a class_interface to get notification of a new class device being added to the system.)
Oh, this also allows us to have the possibility of potentially, someday, moving /sys/block into /sys/class. The main hindrance is that pesky /dev numberspace issue...
--- drivers/base/class.c | 125 +++++++++++++++++++++++++++++++------------------ include/linux/device.h | 13 +++-- 2 files changed, 91 insertions(+), 47 deletions(-)
drivers/base/class.c +81 -44
@@ -99,7 +99,8 @@ struct class * class_get(struct class *void class_put (struct class * cls) { -subsys_put (&cls->subsys); +if (cls) +subsys_put (&cls->subsys); }
@@ -165,14 +166,25 @@ void class_unregister(struct class * clsstatic void class_create_release (struct class *cls) { +pr_debug ("%s called for %s\n" , __FUNCTION__, cls->name);kfree (cls); }static void class_device_create_release (struct class_device *class_dev) { +pr_debug ("%s called for %s\n" , __FUNCTION__, class_dev->class_id);kfree (class_dev); } +/* needed to allow these devices to have parent class devices */ +static int class_device_create_hotplug (struct class_device *class_dev, +char **envp,int num_envp, +char *buffer,int buffer_size) +{ +pr_debug ("%s called for %s\n" , __FUNCTION__, class_dev->class_id); +return 0 ; +} +/** * class_create - create a struct class structure * @owner: pointer to the module that is to "own" this struct class
@@ -301,10 +313,12 @@ static void class_dev_release(struct kobkfree (cd->devt_attr); cd->devt_attr =NULL ; -if (cls->release) +if (cd->release) + cd->release (cd); +else if (cls->release) cls->release (cd);else { -printk (KERN_ERR "Device class '%s' does not have a release() function, " +printk (KERN_ERR "Class Device '%s' does not have a release() function, " "it is broken and must be fixed.\n" , cd->class_id);WARN_ON (1 );
@@ -382,14 +396,18 @@ static int class_hotplug(struct kset *ks buffer = &buffer[length]; buffer_size -= length; -if (class_dev->class->hotplug) { -/* have the bus specific function add its stuff */ - retval = class_dev->class->hotplug (class_dev, envp, num_envp, - buffer, buffer_size); -if (retval) { -pr_debug ("%s - hotplug() returned %d\n" , - __FUNCTION__, retval); - } +if (class_dev->hotplug) { +/* have the class device specific function add its stuff */ + retval = class_dev->hotplug (class_dev, envp, num_envp, + buffer, buffer_size); +if (retval) +pr_debug ("class_dev->hotplug() returned %d\n" , retval); + }else if (class_dev->class->hotplug) { +/* have the class specific function add its stuff */ + retval = class_dev->class->hotplug (class_dev, envp, num_envp, + buffer, buffer_size); +if (retval) +pr_debug ("class->hotplug() returned %d\n" , retval); }return retval;
@@ -476,37 +494,42 @@ static char *make_class_name(struct clasint class_device_add (struct class_device *class_dev) { -struct class * parent =NULL ; -struct class_interface * class_intf; +struct class *parent_class =NULL ; +struct class_device *parent_class_dev =NULL ; +struct class_interface *class_intf;char *class_name =NULL ; -int error; +int error = -EINVAL ; class_dev =class_device_get (class_dev);if (!class_dev)return -EINVAL ; -if (!strlen (class_dev->class_id)) { - error = -EINVAL ; +if (!strlen (class_dev->class_id)) goto register_done; - } - parent =class_get (class_dev->class); + parent_class =class_get (class_dev->class); +if (!parent_class) + goto register_done; + parent_class_dev =class_device_get (class_dev->parent);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 (parent_class_dev) + class_dev->kobj.parent = &parent_class_dev->kobj; +else + class_dev->kobj.parent = &parent_class->subsys.kset.kobj; -if ((error =kobject_add (&class_dev->kobj))) + error =kobject_add (&class_dev->kobj); +if (error) goto register_done;/* add the needed attributes to this device */ class_dev->uevent_attr.attr.name ="uevent" ; class_dev->uevent_attr.attr.mode =S_IWUSR ; - class_dev->uevent_attr.attr.owner = parent->owner; + class_dev->uevent_attr.attr.owner = parent_class->owner; class_dev->uevent_attr.store = store_uevent;class_device_create_file (class_dev, &class_dev->uevent_attr);
@@ -520,7 +543,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 = parent_class->owner; attr->show = show_dev;class_device_create_file (class_dev, attr); class_dev->devt_attr = attr;
@@ -538,18 +561,20 @@ int class_device_add(struct class_devicekobject_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 (parent_class) { +down (&parent_class->sem); +list_add_tail (&class_dev->node, &parent_class->children); +list_for_each_entry (class_intf, &parent_class->interfaces, node)if (class_intf->add) class_intf->add (class_dev, class_intf); -up (&parent->sem); +up (&parent_class->sem); } register_done: -if (error && parent) -class_put (parent); +if (error) { +class_put (parent_class); +class_device_put (parent_class_dev); + }class_device_put (class_dev);kfree (class_name);return error;
@@ -564,21 +589,28 @@ int class_device_register(struct class_d/** * class_device_create - creates a class device and registers it with sysfs * @cs: pointer to the struct class that this device should be registered to. +* @parent: pointer to the parent struct class_device of this new device, if any. * @dev: the dev_t for the char device to be added. * @device: a pointer to a struct device that is assiociated with this class device. * @fmt: string for the class device's name * * This function can be used by char device classes. A struct * class_device will be created in sysfs, registered to the specified -* class. A "dev" file will be created, showing the dev_t for the -* device. The pointer to the struct class_device will be returned from -* the call. Any further sysfs files that might be required can be -* created using this pointer. +* class. +* A "dev" file will be created, showing the dev_t for the device, if +* the dev_t is not 0,0. +* If a pointer to a parent struct class_device is passed in, the newly +* created struct class_device will be a child of that device in sysfs. +* The pointer to the struct class_device will be returned from the +* call. Any further sysfs files that might be required can be created +* using this pointer. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ -struct class_device *class_device_create (struct class *cls,dev_t devt, +struct class_device *class_device_create (struct class *cls, +struct class_device *parent, +dev_t devt,struct device *device,char *fmt, ...) {va_list args;
@@ -597,6 +629,9 @@ struct class_device *class_device_create class_dev->devt = devt; class_dev->dev = device; class_dev->class = cls; + class_dev->parent = parent; + class_dev->release = class_device_create_release; + class_dev->hotplug = class_device_create_hotplug;va_start (args, fmt);vsnprintf (class_dev->class_id,BUS_ID_SIZE , fmt, args);
@@ -614,17 +649,18 @@ error:void class_device_del (struct class_device *class_dev) { -struct class * parent = class_dev->class; -struct class_interface * class_intf; +struct class *parent_class = class_dev->class; +struct class_device *parent_device = class_dev->parent; +struct class_interface *class_intf;char *class_name =NULL ; -if (parent) { -down (&parent->sem); +if (parent_class) { +down (&parent_class->sem);list_del_init (&class_dev->node); -list_for_each_entry (class_intf, &parent->interfaces, node) +list_for_each_entry (class_intf, &parent_class->interfaces, node)if (class_intf->remove) class_intf->remove (class_dev, class_intf); -up (&parent->sem); +up (&parent_class->sem); }if (class_dev->dev) {
@@ -640,8 +676,8 @@ void class_device_del(struct class_devickobject_hotplug (&class_dev->kobj,KOBJ_REMOVE );kobject_del (&class_dev->kobj); -if (parent) -class_put (parent); +class_device_put (parent_device); +class_put (parent_class);kfree (class_name); }
@@ -721,7 +757,8 @@ struct class_device * class_device_get(svoid class_device_put (struct class_device *class_dev) { -kobject_put (&class_dev->kobj); +if (class_dev) +kobject_put (&class_dev->kobj); }
include/linux/device.h +10 -3
@@ -213,7 +213,11 @@ struct class_device {struct class_device_attribute uevent_attr;struct device * dev;/* not necessary, but nice to have */ void * class_data;/* class-specific data */ +struct class_device *parent;/* parent of this child device, if there is one */ +void (*release)(struct class_device *dev); +int (*hotplug)(struct class_device *dev,char **envp, +int num_envp,char *buffer,int buffer_size);char class_id[BUS_ID_SIZE ];/* unique to this class */ };
@@ -261,9 +265,12 @@ extern void class_interface_unregister(sextern struct class *class_create (struct module *owner,char *name);extern void class_destroy (struct class *cls); -extern struct class_device *class_device_create (struct class *cls,dev_t devt, -struct device *device,char *fmt, ...) - __attribute__((format (printf,4 ,5 ))); +extern struct class_device *class_device_create (struct class *cls, +struct class_device *parent, +dev_t devt, +struct device *device, +char *fmt, ...) + __attribute__((format (printf,5 ,6 )));extern void class_device_destroy (struct class *cls,dev_t devt);
--
PATCH 2/8 Driver Core: fix up all callers of class_device_create()
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
The previous patch adding the ability to nest struct class_device changed the paramaters to the call class_device_create(). This patch fixes up all in-kernel users of the function.
--- arch/i386/kernel/cpuid.c | 2 +- arch/i386/kernel/msr.c | 2 +- drivers/block/aoe/aoechr.c | 2 +- drivers/block/paride/pg.c | 2 +- drivers/block/paride/pt.c | 4 ++-- drivers/char/dsp56k.c | 2 +- drivers/char/ftape/zftape/zftape-init.c | 12 ++++++------ drivers/char/ip2main.c | 10 ++++++---- drivers/char/ipmi/ipmi_devintf.c | 2 +- drivers/char/istallion.c | 3 ++- drivers/char/lp.c | 2 +- drivers/char/mem.c | 3 ++- drivers/char/misc.c | 2 +- drivers/char/ppdev.c | 2 +- drivers/char/raw.c | 4 ++-- drivers/char/snsc.c | 2 +- drivers/char/stallion.c | 4 +++- drivers/char/tipar.c | 2 +- drivers/char/tty_io.c | 10 +++++----- drivers/char/vc_screen.c | 10 ++++++---- drivers/char/viotape.c | 4 ++-- drivers/hwmon/hwmon.c | 2 +- drivers/ide/ide-tape.c | 4 ++-- drivers/ieee1394/dv1394.c | 2 +- drivers/ieee1394/raw1394.c | 2 +- drivers/ieee1394/video1394.c | 2 +- drivers/infiniband/core/ucm.c | 2 +- drivers/input/evdev.c | 2 +- drivers/input/joydev.c | 2 +- drivers/input/mousedev.c | 4 ++-- drivers/input/tsdev.c | 2 +- drivers/isdn/capi/capi.c | 2 +- drivers/macintosh/adb.c | 2 +- drivers/media/dvb/dvb-core/dvbdev.c | 2 +- drivers/message/i2o/iop.c | 2 +- drivers/mtd/mtdchar.c | 4 ++-- drivers/net/ppp_generic.c | 2 +- drivers/net/wan/cosa.c | 2 +- drivers/s390/char/tape_class.c | 1 + drivers/s390/char/vmlogrdr.c | 1 + drivers/scsi/ch.c | 2 +- drivers/scsi/osst.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/scsi/st.c | 2 +- drivers/usb/core/devio.c | 2 +- drivers/usb/core/file.c | 4 +++- drivers/usb/core/hcd.c | 3 ++- drivers/video/fbmem.c | 2 +- fs/coda/psdev.c | 4 ++-- sound/core/sound.c | 2 +- sound/oss/soundcard.c | 4 ++-- sound/sound_core.c | 2 +- 52 files changed, 86 insertions(+), 73 deletions(-)
drivers/usb/core/devio.c +1 -1
@@ -1509,7 +1509,7 @@ void usbdev_add(struct usb_device *dev) {int minor = ((dev->bus->busnum-1 ) *128 ) + (dev->devnum-1 ); - dev->class_dev =class_device_create (usb_device_class, + dev->class_dev =class_device_create (usb_device_class,NULL ,MKDEV (USB_DEVICE_MAJOR , minor), &dev->dev,"usbdev%d.%d" , dev->bus->busnum, dev->devnum);
drivers/usb/core/file.c +3 -1
@@ -172,7 +172,9 @@ int usb_register_dev(struct usb_interfac ++temp; else temp = name; - intf->class_dev =class_device_create (usb_class,MKDEV (USB_MAJOR , minor), &intf->dev,"%s" , temp); + intf->class_dev =class_device_create (usb_class,NULL , +MKDEV (USB_MAJOR , minor), + &intf->dev,"%s" , temp);if (IS_ERR (intf->class_dev)) {spin_lock (&minor_lock); usb_minors[intf->minor] =NULL ;
drivers/usb/core/hcd.c +2 -1
@@ -782,7 +782,8 @@ static int usb_register_bus(struct usb_breturn -E2BIG ; } - bus->class_dev =class_device_create (usb_host_class,MKDEV (0 ,0 ), bus->controller,"usb_host%d" , busnum); + bus->class_dev =class_device_create (usb_host_class,NULL ,MKDEV (0 ,0 ), + bus->controller,"usb_host%d" , busnum);if (IS_ERR (bus->class_dev)) {clear_bit (busnum, busmap.busmap);up (&usb_bus_list_lock);
drivers/video/fbmem.c +1 -1
@@ -1031,7 +1031,7 @@ register_framebuffer(struct fb_info *fb_break ; fb_info->node = i; - fb_info->class_device =class_device_create (fb_class,MKDEV (FB_MAJOR , i), + fb_info->class_device =class_device_create (fb_class,NULL ,MKDEV (FB_MAJOR , i), fb_info->device,"fb%d" , i);if (IS_ERR (fb_info->class_device)) {/* Not fatal */
drivers/block/aoe/aoechr.c +1 -1
@@ -224,7 +224,7 @@ aoechr_init(void)return PTR_ERR (aoe_class); }for (i =0 ; i <ARRAY_SIZE (chardevs); ++i) -class_device_create (aoe_class, +class_device_create (aoe_class,NULL ,MKDEV (AOE_MAJOR , chardevs[i].minor),NULL , chardevs[i].name);
drivers/block/paride/pg.c +1 -1
@@ -674,7 +674,7 @@ static int __init pg_init(void)for (unit =0 ; unit <PG_UNITS ; unit++) {struct pg *dev = &devices[unit];if (dev->present) { -class_device_create (pg_class,MKDEV (major, unit), +class_device_create (pg_class,NULL ,MKDEV (major, unit),NULL ,"pg%u" , unit); err = devfs_mk_cdev(MKDEV(major, unit), S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
drivers/block/paride/pt.c +2 -2
@@ -971,7 +971,7 @@ static int __init pt_init(void)devfs_mk_dir ("pt" );for (unit =0 ; unit <PT_UNITS ; unit++)if (pt[unit].present) { -class_device_create (pt_class,MKDEV (major, unit), +class_device_create (pt_class,NULL ,MKDEV (major, unit),NULL ,"pt%d" , unit); err = devfs_mk_cdev(MKDEV(major, unit), S_IFCHR | S_IRUSR | S_IWUSR,
@@ -980,7 +980,7 @@ static int __init pt_init(void)class_device_destroy (pt_class,MKDEV (major, unit)); goto out_class; } -class_device_create (pt_class,MKDEV (major, unit +128 ), +class_device_create (pt_class,NULL ,MKDEV (major, unit +128 ),NULL ,"pt%dn" , unit); err = devfs_mk_cdev(MKDEV(major, unit + 128), S_IFCHR | S_IRUSR | S_IWUSR,
drivers/char/dsp56k.c +1 -1
@@ -515,7 +515,7 @@ static int __init dsp56k_init_driver(voi err =PTR_ERR (dsp56k_class); goto out_chrdev; } -class_device_create (dsp56k_class,MKDEV (DSP56K_MAJOR ,0 ),NULL ,"dsp56k" ); +class_device_create (dsp56k_class,NULL ,MKDEV (DSP56K_MAJOR ,0 ),NULL ,"dsp56k" ); err =devfs_mk_cdev (MKDEV (DSP56K_MAJOR ,0 ),S_IFCHR |S_IRUSR |S_IWUSR ,"dsp56k" );
drivers/char/ip2main.c +6 -4
@@ -721,8 +721,9 @@ ip2_loadmain(int *iop, int *irqp, unsign }if (NULL != ( pB = i2BoardPtrTable[i] ) ) { -class_device_create (ip2_class,MKDEV (IP2_IPL_MAJOR , -4 * i),NULL ,"ipl%d" , i); +class_device_create (ip2_class,NULL , +MKDEV (IP2_IPL_MAJOR ,4 * i), +NULL ,"ipl%d" , i); err =devfs_mk_cdev (MKDEV (IP2_IPL_MAJOR ,4 * i),S_IRUSR |S_IWUSR |S_IRGRP |S_IFCHR ,"ip2/ipl%d" , i);
@@ -732,8 +733,9 @@ ip2_loadmain(int *iop, int *irqp, unsign goto out_class; } -class_device_create (ip2_class,MKDEV (IP2_IPL_MAJOR , -4 * i +1 ),NULL ,"stat%d" , i); +class_device_create (ip2_class,NULL , +MKDEV (IP2_IPL_MAJOR ,4 * i +1 ), +NULL ,"stat%d" , i); err =devfs_mk_cdev (MKDEV (IP2_IPL_MAJOR ,4 * i +1 ),S_IRUSR |S_IWUSR |S_IRGRP |S_IFCHR ,"ip2/stat%d" , i);
drivers/char/istallion.c +2 -1
@@ -5246,7 +5246,8 @@ int __init stli_init(void)devfs_mk_cdev (MKDEV (STL_SIOMEMMAJOR , i),S_IFCHR |S_IRUSR |S_IWUSR ,"staliomem/%d" , i); -class_device_create (istallion_class,MKDEV (STL_SIOMEMMAJOR , i), +class_device_create (istallion_class,NULL , +MKDEV (STL_SIOMEMMAJOR , i),NULL ,"staliomem%d" , i); }
drivers/char/lp.c +1 -1
@@ -805,7 +805,7 @@ static int lp_register(int nr, struct paif (reset)lp_reset (nr); -class_device_create (lp_class,MKDEV (LP_MAJOR , nr),NULL , +class_device_create (lp_class,NULL ,MKDEV (LP_MAJOR , nr),NULL ,"lp%d" , nr);devfs_mk_cdev (MKDEV (LP_MAJOR , nr),S_IFCHR |S_IRUGO |S_IWUGO ,"printers/%d" , nr);
drivers/char/mem.c +2 -1
@@ -920,7 +920,8 @@ static int __init chr_dev_init(void) mem_class =class_create (THIS_MODULE ,"mem" );for (i =0 ; i <ARRAY_SIZE (devlist); i++) { -class_device_create (mem_class,MKDEV (MEM_MAJOR , devlist[i].minor), +class_device_create (mem_class,NULL , +MKDEV (MEM_MAJOR , devlist[i].minor),NULL , devlist[i].name);devfs_mk_cdev (MKDEV (MEM_MAJOR , devlist[i].minor),S_IFCHR | devlist[i].mode, devlist[i].name);
drivers/char/misc.c +1 -1
@@ -234,7 +234,7 @@ int misc_register(struct miscdevice * mi } dev =MKDEV (MISC_MAJOR , misc->minor); - misc->class =class_device_create (misc_class, dev, misc->dev, + misc->class =class_device_create (misc_class,NULL , dev, misc->dev,"%s" , misc->name);if (IS_ERR (misc->class)) { err =PTR_ERR (misc->class);
drivers/char/ppdev.c +1 -1
@@ -752,7 +752,7 @@ static struct file_operations pp_fops =static void pp_attach (struct parport *port) { -class_device_create (ppdev_class,MKDEV (PP_MAJOR , port->number), +class_device_create (ppdev_class,NULL ,MKDEV (PP_MAJOR , port->number),NULL ,"parport%d" , port->number); }
drivers/char/raw.c +2 -2
@@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct fistatic void bind_device (struct raw_config_request *rq) {class_device_destroy (raw_class,MKDEV (RAW_MAJOR , rq->raw_minor)); -class_device_create (raw_class,MKDEV (RAW_MAJOR , rq->raw_minor), +class_device_create (raw_class,NULL ,MKDEV (RAW_MAJOR , rq->raw_minor),NULL ,"raw%d" , rq->raw_minor); }
@@ -307,7 +307,7 @@ static int __init raw_init(void)unregister_chrdev_region (dev,MAX_RAW_MINORS ); goto error; } -class_device_create (raw_class,MKDEV (RAW_MAJOR ,0 ),NULL ,"rawctl" ); +class_device_create (raw_class,NULL ,MKDEV (RAW_MAJOR ,0 ),NULL ,"rawctl" ); devfs_mk_cdev(MKDEV(RAW_MAJOR, 0), S_IFCHR | S_IRUGO | S_IWUGO,
drivers/char/snsc.c +1 -1
@@ -437,7 +437,7 @@ scdrv_init(void)continue ; } -class_device_create (snsc_class, dev,NULL , +class_device_create (snsc_class,NULL , dev,NULL ,"%s" , devname); ia64_sn_irtr_intr_enable(scd->scd_nasid,
drivers/char/stallion.c +3 -1
@@ -3095,7 +3095,9 @@ static int __init stl_init(void)devfs_mk_cdev (MKDEV (STL_SIOMEMMAJOR , i),S_IFCHR |S_IRUSR |S_IWUSR ,"staliomem/%d" , i); -class_device_create (stallion_class,MKDEV (STL_SIOMEMMAJOR , i),NULL ,"staliomem%d" , i); +class_device_create (stallion_class,NULL , +MKDEV (STL_SIOMEMMAJOR , i),NULL , +"staliomem%d" , i); } stl_serial->owner =THIS_MODULE ;
drivers/char/tipar.c +1 -1
@@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *p goto out; } -class_device_create (tipar_class,MKDEV (TIPAR_MAJOR , +class_device_create (tipar_class,NULL ,MKDEV (TIPAR_MAJOR ,TIPAR_MINOR + nr),NULL ,"par%d" , nr);/* Use devfs, tree: /dev/ticables/par/[0..2] */ err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
drivers/char/tty_io.c +5 -5
@@ -2728,7 +2728,7 @@ void tty_register_device(struct tty_drivpty_line_name (driver, index, name); elsetty_line_name (driver ,index ,name ); -class_device_create (tty_class, dev, device, name); +class_device_create (tty_class,NULL , dev, device,"%s" , name); }/**
@@ -2983,14 +2983,14 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)panic ("Couldn't register /dev/tty driver\n" );devfs_mk_cdev (MKDEV (TTYAUX_MAJOR ,0 ),S_IFCHR |S_IRUGO |S_IWUGO ,"tty" ); -class_device_create (tty_class,MKDEV (TTYAUX_MAJOR ,0 ),NULL ,"tty" ); +class_device_create (tty_class,NULL ,MKDEV (TTYAUX_MAJOR ,0 ),NULL ,"tty" );cdev_init (&console_cdev, &console_fops);if (cdev_add (&console_cdev,MKDEV (TTYAUX_MAJOR ,1 ),1 ) ||register_chrdev_region (MKDEV (TTYAUX_MAJOR ,1 ),1 ,"/dev/console" ) <0 )panic ("Couldn't register /dev/console driver\n" );devfs_mk_cdev (MKDEV (TTYAUX_MAJOR ,1 ),S_IFCHR |S_IRUSR |S_IWUSR ,"console" ); -class_device_create (tty_class,MKDEV (TTYAUX_MAJOR ,1 ),NULL ,"console" ); +class_device_create (tty_class,NULL ,MKDEV (TTYAUX_MAJOR ,1 ),NULL ,"console" );#ifdef CONFIG_UNIX98_PTYS cdev_init (&ptmx_cdev, &ptmx_fops);
@@ -2998,7 +2998,7 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)panic ("Couldn't register /dev/ptmx driver\n" );devfs_mk_cdev (MKDEV (TTYAUX_MAJOR ,2 ),S_IFCHR |S_IRUGO |S_IWUGO ,"ptmx" ); -class_device_create (tty_class,MKDEV (TTYAUX_MAJOR ,2 ),NULL ,"ptmx" ); +class_device_create (tty_class,NULL ,MKDEV (TTYAUX_MAJOR ,2 ),NULL ,"ptmx" );#endif #ifdef CONFIG_VT
@@ -3007,7 +3007,7 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)panic ("Couldn't register /dev/tty0 driver\n" );devfs_mk_cdev (MKDEV (TTY_MAJOR ,0 ),S_IFCHR |S_IRUSR |S_IWUSR ,"vc/0" ); -class_device_create (tty_class,MKDEV (TTY_MAJOR ,0 ),NULL ,"tty0" ); +class_device_create (tty_class,NULL ,MKDEV (TTY_MAJOR ,0 ),NULL ,"tty0" );vty_init ();#endif
drivers/char/ftape/zftape/zftape-init.c +6 -6
@@ -331,27 +331,27 @@ KERN_INFO zft_class =class_create (THIS_MODULE ,"zft" );for (i =0 ; i <4 ; i++) { -class_device_create (zft_class,MKDEV (QIC117_TAPE_MAJOR , i),NULL ,"qft%i" , i); +class_device_create (zft_class,NULL ,MKDEV (QIC117_TAPE_MAJOR , i),NULL ,"qft%i" , i);devfs_mk_cdev (MKDEV (QIC117_TAPE_MAJOR , i),S_IFCHR |S_IRUSR |S_IWUSR ,"qft%i" , i); -class_device_create (zft_class,MKDEV (QIC117_TAPE_MAJOR , i +4 ),NULL ,"nqft%i" , i); +class_device_create (zft_class,NULL ,MKDEV (QIC117_TAPE_MAJOR , i +4 ),NULL ,"nqft%i" , i);devfs_mk_cdev (MKDEV (QIC117_TAPE_MAJOR , i +4 ),S_IFCHR |S_IRUSR |S_IWUSR ,"nqft%i" , i); -class_device_create (zft_class,MKDEV (QIC117_TAPE_MAJOR , i +16 ),NULL ,"zqft%i" , i); +class_device_create (zft_class,NULL ,MKDEV (QIC117_TAPE_MAJOR , i +16 ),NULL ,"zqft%i" , i);devfs_mk_cdev (MKDEV (QIC117_TAPE_MAJOR , i +16 ),S_IFCHR |S_IRUSR |S_IWUSR ,"zqft%i" , i); -class_device_create (zft_class,MKDEV (QIC117_TAPE_MAJOR , i +20 ),NULL ,"nzqft%i" , i); +class_device_create (zft_class,NULL ,MKDEV (QIC117_TAPE_MAJOR , i +20 ),NULL ,"nzqft%i" , i);devfs_mk_cdev (MKDEV (QIC117_TAPE_MAJOR , i +20 ),S_IFCHR |S_IRUSR |S_IWUSR ,"nzqft%i" , i); -class_device_create (zft_class,MKDEV (QIC117_TAPE_MAJOR , i +32 ),NULL ,"rawqft%i" , i); +class_device_create (zft_class,NULL ,MKDEV (QIC117_TAPE_MAJOR , i +32 ),NULL ,"rawqft%i" , i);devfs_mk_cdev (MKDEV (QIC117_TAPE_MAJOR , i +32 ),S_IFCHR |S_IRUSR |S_IWUSR ,"rawqft%i" , i); -class_device_create (zft_class,MKDEV (QIC117_TAPE_MAJOR , i +36 ),NULL ,"nrawrawqft%i" , i); +class_device_create (zft_class,NULL ,MKDEV (QIC117_TAPE_MAJOR , i +36 ),NULL ,"nrawrawqft%i" , i);devfs_mk_cdev (MKDEV (QIC117_TAPE_MAJOR , i +36 ),S_IFCHR |S_IRUSR |S_IWUSR ,"nrawqft%i" , i);
drivers/char/ipmi/ipmi_devintf.c +1 -1
@@ -798,7 +798,7 @@ static void ipmi_new_smi(int if_num)devfs_mk_cdev (dev,S_IFCHR |S_IRUSR |S_IWUSR ,"ipmidev/%d" , if_num); -class_device_create (ipmi_class, dev,NULL ,"ipmi%d" , if_num); +class_device_create (ipmi_class,NULL , dev,NULL ,"ipmi%d" , if_num); }static void ipmi_smi_gone (int if_num)
drivers/char/vc_screen.c +6 -4
@@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *tdevfs_mk_cdev (MKDEV (VCS_MAJOR , tty->index +129 ),S_IFCHR |S_IRUSR |S_IWUSR ,"vcc/a%u" , tty->index +1 ); -class_device_create (vc_class,MKDEV (VCS_MAJOR , tty->index +1 ),NULL ,"vcs%u" , tty->index +1 ); -class_device_create (vc_class,MKDEV (VCS_MAJOR , tty->index +129 ),NULL ,"vcsa%u" , tty->index +1 ); +class_device_create (vc_class,NULL ,MKDEV (VCS_MAJOR , tty->index +1 ), +NULL ,"vcs%u" , tty->index +1 ); +class_device_create (vc_class,NULL ,MKDEV (VCS_MAJOR , tty->index +129 ), +NULL ,"vcsa%u" , tty->index +1 ); }void vcs_remove_devfs (struct tty_struct *tty) {
@@ -503,7 +505,7 @@ int __init vcs_init(void)devfs_mk_cdev (MKDEV (VCS_MAJOR ,0 ),S_IFCHR |S_IRUSR |S_IWUSR ,"vcc/0" );devfs_mk_cdev (MKDEV (VCS_MAJOR ,128 ),S_IFCHR |S_IRUSR |S_IWUSR ,"vcc/a0" ); -class_device_create (vc_class,MKDEV (VCS_MAJOR ,0 ),NULL ,"vcs" ); -class_device_create (vc_class,MKDEV (VCS_MAJOR ,128 ),NULL ,"vcsa" ); +class_device_create (vc_class,NULL ,MKDEV (VCS_MAJOR ,0 ),NULL ,"vcs" ); +class_device_create (vc_class,NULL ,MKDEV (VCS_MAJOR ,128 ),NULL ,"vcsa" );return 0 ; }
drivers/char/viotape.c +2 -2
@@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev state[i].cur_part =0 ;for (j =0 ; j <MAX_PARTITIONS ; ++j) state[i].part_stat_rwi[j] =VIOT_IDLE ; -class_device_create (tape_class,MKDEV (VIOTAPE_MAJOR , i),NULL , +class_device_create (tape_class,NULL ,MKDEV (VIOTAPE_MAJOR , i),NULL ,"iseries!vt%d" , i); -class_device_create (tape_class,MKDEV (VIOTAPE_MAJOR , i |0x80 ), +class_device_create (tape_class,NULL ,MKDEV (VIOTAPE_MAJOR , i |0x80 ),NULL ,"iseries!nvt%d" , i);devfs_mk_cdev (MKDEV (VIOTAPE_MAJOR , i),S_IFCHR |S_IRUSR |S_IWUSR ,"iseries/vt%d" , i);
drivers/hwmon/hwmon.c +1 -1
@@ -45,7 +45,7 @@ struct class_device *hwmon_device_registreturn ERR_PTR (-ENOMEM ); id = id &MAX_ID_MASK ; - cdev =class_device_create (hwmon_class,MKDEV (0 ,0 ), dev, + cdev =class_device_create (hwmon_class,NULL ,MKDEV (0 ,0 ), dev,HWMON_ID_FORMAT , id);if (IS_ERR (cdev))
drivers/ide/ide-tape.c +2 -2
@@ -4884,9 +4884,9 @@ static int ide_tape_probe(struct deviceidetape_setup (drive, tape, minor); -class_device_create (idetape_sysfs_class, +class_device_create (idetape_sysfs_class,NULL ,MKDEV (IDETAPE_MAJOR , minor), dev,"%s" , tape->name); -class_device_create (idetape_sysfs_class, +class_device_create (idetape_sysfs_class,NULL ,MKDEV (IDETAPE_MAJOR , minor +128 ), dev,"n%s" , tape->name); devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
drivers/ieee1394/dv1394.c +1 -1
@@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb ohci = (struct ti_ohci *)host->hostdata; -class_device_create (hpsb_protocol_class,MKDEV ( +class_device_create (hpsb_protocol_class,NULL ,MKDEV (IEEE1394_MAJOR ,IEEE1394_MINOR_BLOCK_DV1394 *16 + (id<<2 )),NULL ,"dv1394-%d" , id);devfs_mk_dir ("ieee1394/dv/host%d" , id);
drivers/ieee1394/raw1394.c +1 -1
@@ -2904,7 +2904,7 @@ static int __init init_raw1394(void)hpsb_register_highlevel (&raw1394_highlevel); -if (IS_ERR (class_device_create (hpsb_protocol_class,MKDEV ( +if (IS_ERR (class_device_create (hpsb_protocol_class,NULL ,MKDEV (IEEE1394_MAJOR ,IEEE1394_MINOR_BLOCK_RAW1394 *16 ),NULL ,RAW1394_DEVICE_NAME ))) { ret = -EFAULT ;
drivers/ieee1394/video1394.c +1 -1
@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct hhpsb_set_hostinfo_key (&video1394_highlevel, host, ohci->host->id); minor =IEEE1394_MINOR_BLOCK_VIDEO1394 *16 + ohci->host->id; -class_device_create (hpsb_protocol_class,MKDEV ( +class_device_create (hpsb_protocol_class,NULL ,MKDEV (IEEE1394_MAJOR , minor),NULL ,"%s-%d" ,VIDEO1394_DRIVER_NAME , ohci->host->id); devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
drivers/infiniband/core/ucm.c +1 -1
@@ -1300,7 +1300,7 @@ static int __init ib_ucm_init(void) goto err_class; } -class_device_create (ib_ucm_class,IB_UCM_DEV ,NULL ,"ucm" ); +class_device_create (ib_ucm_class,NULL ,IB_UCM_DEV ,NULL ,"ucm" );idr_init (&ctx_id_table);init_MUTEX (&ctx_id_mutex);
drivers/isdn/capi/capi.c +1 -1
@@ -1505,7 +1505,7 @@ static int __init capi_init(void)return PTR_ERR (capi_class); } -class_device_create (capi_class,MKDEV (capi_major,0 ),NULL ,"capi" ); +class_device_create (capi_class,NULL ,MKDEV (capi_major,0 ),NULL ,"capi" );devfs_mk_cdev (MKDEV (capi_major,0 ),S_IFCHR |S_IRUSR |S_IWUSR ,"isdn/capi20" );
drivers/macintosh/adb.c +1 -1
@@ -905,5 +905,5 @@ adbdev_init(void) adb_dev_class =class_create (THIS_MODULE ,"adb" );if (IS_ERR (adb_dev_class))return ; -class_device_create (adb_dev_class,MKDEV (ADB_MAJOR ,0 ),NULL ,"adb" ); +class_device_create (adb_dev_class,NULL ,MKDEV (ADB_MAJOR ,0 ),NULL ,"adb" ); }
drivers/media/dvb/dvb-core/dvbdev.c +1 -1
@@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adaptS_IFCHR |S_IRUSR |S_IWUSR , "dvb/adapter%d/%s%d", adap->num, dnames[type], id); -class_device_create (dvb_class,MKDEV (DVB_MAJOR ,nums2minor (adap->num, type, id)), +class_device_create (dvb_class,NULL ,MKDEV (DVB_MAJOR ,nums2minor (adap->num, type, id)),NULL ,"dvb%d.%s%d" , adap->num, dnames[type], id); dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
drivers/message/i2o/iop.c +1 -1
@@ -1141,7 +1141,7 @@ int i2o_iop_add(struct i2o_controller *c goto iop_reset; } - c->classdev =class_device_create (i2o_controller_class,0 , + c->classdev =class_device_create (i2o_controller_class,NULL ,MKDEV (0 ,0 ), &c->device,"iop%d" , c->unit);if (IS_ERR (c->classdev)) {osm_err ("%s: could not add controller class\n" , c->name);
drivers/mtd/mtdchar.c +2 -2
@@ -24,10 +24,10 @@ static void mtd_notify_add(struct mtd_inif (!mtd)return ; -class_device_create (mtd_class,MKDEV (MTD_CHAR_MAJOR , mtd->index*2 ), +class_device_create (mtd_class,NULL ,MKDEV (MTD_CHAR_MAJOR , mtd->index*2 ),NULL ,"mtd%d" , mtd->index); -class_device_create (mtd_class, +class_device_create (mtd_class,NULL ,MKDEV (MTD_CHAR_MAJOR , mtd->index*2 +1 ),NULL ,"mtd%dro" , mtd->index); }
drivers/net/ppp_generic.c +1 -1
@@ -863,7 +863,7 @@ static int __init ppp_init(void) err =PTR_ERR (ppp_class); goto out_chrdev; } -class_device_create (ppp_class,MKDEV (PPP_MAJOR ,0 ),NULL ,"ppp" ); +class_device_create (ppp_class,NULL ,MKDEV (PPP_MAJOR ,0 ),NULL ,"ppp" ); err =devfs_mk_cdev (MKDEV (PPP_MAJOR ,0 ),S_IFCHR |S_IRUSR |S_IWUSR ,"ppp" );if (err)
drivers/net/wan/cosa.c +1 -1
@@ -400,7 +400,7 @@ static int __init cosa_init(void) goto out_chrdev; }for (i=0 ; i<nr_cards; i++) { -class_device_create (cosa_class,MKDEV (cosa_major, i), +class_device_create (cosa_class,NULL ,MKDEV (cosa_major, i),NULL ,"cosa%d" , i); err = devfs_mk_cdev(MKDEV(cosa_major, i), S_IFCHR|S_IRUSR|S_IWUSR,
drivers/s390/char/tape_class.c +1 -0
@@ -72,6 +72,7 @@ struct tape_class_device *register_tape_ tcd->class_device =class_device_create ( tape_class, +NULL , tcd->char_device->dev, device, "%s", tcd->device_name
drivers/s390/char/vmlogrdr.c +1 -0
@@ -787,6 +787,7 @@ vmlogrdr_register_device(struct vmlogrdrreturn ret; } priv->class_device = class_device_create( + NULL, vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num), dev,
drivers/scsi/ch.c +1 -1
@@ -936,7 +936,7 @@ static int ch_probe(struct device *dev)if (init)ch_init_elem (ch); -class_device_create (ch_sysfs_class, +class_device_create (ch_sysfs_class,NULL ,MKDEV (SCSI_CHANGER_MAJOR ,ch->minor), dev,"s%s" , ch->name);
drivers/scsi/osst.c +1 -1
@@ -5627,7 +5627,7 @@ static void osst_sysfs_add(dev_t dev, stif (!osst_sysfs_valid)return ; - osst_class_member =class_device_create (osst_sysfs_class, dev, device,"%s" , name); + osst_class_member =class_device_create (osst_sysfs_class,NULL , dev, device,"%s" , name);if (IS_ERR (osst_class_member)) {printk (KERN_WARNING "osst :W: Unable to add sysfs class member %s\n" , name);return ;
drivers/scsi/sg.c +1 -1
@@ -1550,7 +1550,7 @@ sg_add(struct class_device *cl_dev, struif (sg_sysfs_valid) {struct class_device * sg_class_member; - sg_class_member =class_device_create (sg_sysfs_class, + sg_class_member =class_device_create (sg_sysfs_class,NULL ,MKDEV (SCSI_GENERIC_MAJOR , k), cl_dev->dev,"%s" , disk->disk_name);
drivers/scsi/st.c +1 -1
@@ -4375,7 +4375,7 @@ static void do_create_class_files(structsnprintf (name,10 ,"%s%s%s" , rew ?"n" :"" , STp->disk->disk_name, st_formats[i]); st_class_member = -class_device_create (st_sysfs_class, +class_device_create (st_sysfs_class,NULL ,MKDEV (SCSI_TAPE_MAJOR ,TAPE_MINOR (dev_num, mode, rew)), &STp->device->sdev_gendev,"%s" , name);
drivers/input/evdev.c +1 -1
@@ -689,7 +689,7 @@ static struct input_handle *evdev_connecdevfs_mk_cdev (MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + minor),S_IFCHR |S_IRUGO |S_IWUSR ,"input/event%d" , minor); -class_device_create (input_class, +class_device_create (input_class,NULL ,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + minor), dev->dev,"event%d" , minor);
drivers/input/joydev.c +1 -1
@@ -516,7 +516,7 @@ static struct input_handle *joydev_connedevfs_mk_cdev (MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + minor),S_IFCHR |S_IRUGO |S_IWUSR ,"input/js%d" , minor); -class_device_create (input_class, +class_device_create (input_class,NULL ,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + minor), dev->dev,"js%d" , minor);
drivers/input/mousedev.c +2 -2
@@ -651,7 +651,7 @@ static struct input_handle *mousedev_condevfs_mk_cdev (MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE + minor),S_IFCHR |S_IRUGO |S_IWUSR ,"input/mouse%d" , minor); -class_device_create (input_class, +class_device_create (input_class,NULL ,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE + minor), dev->dev,"mouse%d" , minor);
@@ -740,7 +740,7 @@ static int __init mousedev_init(void)devfs_mk_cdev (MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE +MOUSEDEV_MIX ),S_IFCHR |S_IRUGO |S_IWUSR ,"input/mice" ); -class_device_create (input_class, +class_device_create (input_class,NULL ,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE +MOUSEDEV_MIX ),NULL ,"mice" );#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
drivers/input/tsdev.c +1 -1
@@ -414,7 +414,7 @@ static struct input_handle *tsdev_connec S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);devfs_mk_cdev (MKDEV (INPUT_MAJOR ,TSDEV_MINOR_BASE + minor +TSDEV_MINORS /2 ),S_IFCHR |S_IRUGO |S_IWUSR ,"input/tsraw%d" , minor); -class_device_create (input_class, +class_device_create (input_class,NULL ,MKDEV (INPUT_MAJOR ,TSDEV_MINOR_BASE + minor), dev->dev,"ts%d" , minor);
arch/i386/kernel/cpuid.c +1 -1
@@ -163,7 +163,7 @@ static int cpuid_class_device_create(intint err =0 ;struct class_device *class_err; - class_err =class_device_create (cpuid_class,MKDEV (CPUID_MAJOR , i),NULL ,"cpu%d" ,i); + class_err =class_device_create (cpuid_class,NULL ,MKDEV (CPUID_MAJOR , i),NULL ,"cpu%d" ,i);if (IS_ERR (class_err)) err =PTR_ERR (class_err);return err;
arch/i386/kernel/msr.c +1 -1
@@ -246,7 +246,7 @@ static int msr_class_device_create(int iint err =0 ;struct class_device *class_err; - class_err =class_device_create (msr_class,MKDEV (MSR_MAJOR , i),NULL ,"msr%d" ,i); + class_err =class_device_create (msr_class,NULL ,MKDEV (MSR_MAJOR , i),NULL ,"msr%d" ,i);if (IS_ERR (class_err)) err =PTR_ERR (class_err);return err;
sound/core/sound.c +1 -1
@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_cadevfs_mk_cdev (MKDEV (major, minor),S_IFCHR | device_mode,"snd/%s" , name);if (card) device = card->dev; -class_device_create (sound_class,MKDEV (major, minor), device,"%s" , name); +class_device_create (sound_class,NULL ,MKDEV (major, minor), device,"%s" , name);up (&sound_mutex);return 0 ;
sound/oss/soundcard.c +2 -2
@@ -567,7 +567,7 @@ static int __init oss_init(void)devfs_mk_cdev (MKDEV (SOUND_MAJOR , dev_list[i].minor),S_IFCHR | dev_list[i].mode,"sound/%s" , dev_list[i].name); -class_device_create (sound_class, +class_device_create (sound_class,NULL ,MKDEV (SOUND_MAJOR , dev_list[i].minor),NULL ,"%s" , dev_list[i].name);
@@ -579,7 +579,7 @@ static int __init oss_init(void) dev_list[i].minor + (j*0x10)),S_IFCHR | dev_list[i].mode, "sound/%s%d", dev_list[i].name, j); -class_device_create (sound_class, +class_device_create (sound_class,NULL ,MKDEV (SOUND_MAJOR , dev_list[i].minor + (j*0x10 )),NULL ,"%s%d" , dev_list[i].name, j); }
sound/sound_core.c +1 -1
@@ -174,7 +174,7 @@ static int sound_insert_unit(struct soundevfs_mk_cdev (MKDEV (SOUND_MAJOR , s->unit_minor),S_IFCHR | mode, s->name); -class_device_create (sound_class,MKDEV (SOUND_MAJOR , s->unit_minor), +class_device_create (sound_class,NULL ,MKDEV (SOUND_MAJOR , s->unit_minor), dev, s->name+6 );return r;
fs/coda/psdev.c +2 -2
@@ -370,8 +370,8 @@ static int init_coda_psdev(void) }devfs_mk_dir ("coda" );for (i =0 ; i <MAX_CODADEVS ; i++) { -class_device_create (coda_psdev_class,MKDEV (CODA_PSDEV_MAJOR ,i), -NULL ,"cfs%d" , i); +class_device_create (coda_psdev_class,NULL , +MKDEV (CODA_PSDEV_MAJOR ,i),NULL ,"cfs%d" , i); err =devfs_mk_cdev (MKDEV (CODA_PSDEV_MAJOR , i),S_IFCHR |S_IRUSR |S_IWUSR ,"coda/%d" , i);if (err)
--
PATCH 3/8 Driver Core: document struct class_device properly
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
--- include/linux/device.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
include/linux/device.h +24 -0
@@ -203,6 +203,30 @@ struct class_device_attribute class_deviextern int class_device_create_file (struct class_device *,const struct class_device_attribute *); +/** +* struct class_device - class devices +* @class: pointer to the parent class for this class device. This is required. +* @devt: for internal use by the driver core only. +* @node: for internal use by the driver core only. +* @kobj: for internal use by the driver core only. +* @devt_attr: for internal use by the driver core only. +* @dev: if set, a symlink to the struct device is created in the sysfs +* directory for this struct class device. +* @class_data: pointer to whatever you want to store here for this struct +* class_device. Use class_get_devdata() and class_set_devdata() to get and +* set this pointer. +* @parent: pointer to a struct class_device that is the parent of this struct +* class_device. If NULL, this class_device will show up at the root of the +* struct class in sysfs (which is probably what you want to have happen.) +* @release: pointer to a release function for this struct class_device. If +* set, this will be called instead of the class specific release function. +* Only use this if you want to override the default release function, like +* when you are nesting class_device structures. +* @hotplug: pointer to a hotplug function for this struct class_device. If +* set, this will be called instead of the class specific hotplug function. +* Only use this if you want to override the default hotplug function, like +* when you are nesting class_device structures. +*/ struct class_device {struct list_head node;
--
PATCH 4/8 input: register the input class device sooner
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
This is needed so we can actually use the class device within the input handlers.
--- drivers/input/input.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/input/input.c +3 -3
@@ -795,6 +795,9 @@ void input_register_device(struct input_INIT_LIST_HEAD (&dev->h_list);list_add_tail (&dev->node, &input_dev_list); +if (dev->dynalloc) +input_register_classdevice (dev); +list_for_each_entry (handler, &input_handler_list, node)if (!handler->blacklist || !input_match_device (handler->blacklist, dev))if ((id =input_match_device (handler->id_table, dev)))
@@ -802,9 +805,6 @@ void input_register_device(struct input_input_link_handle (handle); -if (dev->dynalloc) -input_register_classdevice (dev); -#ifdef CONFIG_HOTPLUG input_call_hotplug ("add" , dev);#endif
--
Quoted 5 lines · Greg KH
Ok, finally. Here's a set of _working_ patches that properly implement nesting
class_devicestructures, and the follow-on patches to move the input subsystem to use them. Hotplug and release functions work properly now, and this will let us move/sys/block/to use class andclass_devicestructures soon.
Oh, Kay, do you have a public patch to udevstart/udev that can handle this nested structure? It might be good to have that so people can test these in the next -mm.
thanks,
greg k-h
Quoted 10 lines · Greg KH
Quoted 5 lines · Greg KH
Ok, finally. Here's a set of _working_ patches that properly implement nesting
class_devicestructures, and the follow-on patches to move the input subsystem to use them. Hotplug and release functions work properly now, and this will let us move/sys/block/to use class andclass_devicestructures soon.Oh, Kay, do you have a public patch to udevstart/udev that can handle this nested structure? It might be good to have that so people can test these in the next -mm.
Sure, here is an still untested hack. Sorry, I'm "busy" at a conference this week. Anyhow, I still think that we really don't want to nest classes this way. :)
Thanks,
Kay
---
libsysfs/sysfs_class.c +39 -9
@@ -227,16 +227,46 @@ struct sysfs_class_device *sysfs_get_claif (clsdev->parent)return (clsdev->parent); -/* -* As of now, only block devices have a parent child heirarchy in sysfs -* We do not know, if, in the future, more classes will have a similar -* structure. Hence, we now call a specialized function for block and -* later we can add support functions for other subsystems as required. -*/ -if (!(strncmp (clsdev->classname,SYSFS_BLOCK_NAME , -sizeof (SYSFS_BLOCK_NAME )))) { -if ((get_blockdev_parent (clsdev)) ==0 ) +if (!strncmp (clsdev->classname,SYSFS_BLOCK_NAME ,sizeof (SYSFS_BLOCK_NAME ))) { +if ((get_blockdev_parent (clsdev)) ==0 )return (clsdev->parent); + }else if (!strncmp (clsdev->classname,SYSFS_CLASS_NAME ,sizeof (SYSFS_CLASS_NAME ))) { +char ppath[SYSFS_PATH_MAX ]; +char dpath[SYSFS_PATH_MAX ]; +char *tmp; + +memset (ppath,0 ,SYSFS_PATH_MAX ); +memset (dpath,0 ,SYSFS_PATH_MAX ); +safestrcpy (ppath, clsdev->path); + tmp =strrchr (ppath,'/' ); +if (!tmp) { +dprintf ("Invalid path to device %s\n" , ppath); +return NULL ; + } +if (*(tmp +1 ) =='\0' ) { + *tmp ='\0' ; + tmp =strrchr (tmp,'/' ); +if (tmp ==NULL ) { +dprintf ("Invalid path to device %s\n" , ppath); +return NULL ; + } + } + *tmp ='\0' ; + +/* Make sure we're not at the top of the device tree */ +sysfs_get_mnt_path (dpath,SYSFS_PATH_MAX ); +safestrcat (dpath,"/" SYSFS_CLASS_NAME ); +if (strcmp (dpath, ppath) ==0 ) { +dprintf ("Device at %s does not have a parent\n" , clsdev->path); +return NULL ; + } + + clsdev->parent =sysfs_open_class_device_path (ppath); +if (!clsdev->parent) { +dprintf ("Error opening device %s's parent at %s\n" , clsdev->name, ppath); +return NULL ; + } +return (clsdev->parent); }return NULL ; }
udevstart.c +23 -2
@@ -79,7 +79,7 @@ static int device_list_insert(const charstruct device *new_device;const char *devpath = &path[strlen (sysfs_path)]; -dbg ("insert: '%s'\n" , devpath); +dbg ("insert: '%s'" , devpath);list_for_each_entry (loop_device, device_list, node) {if (strcmp (loop_device->path, devpath) >0 ) {
@@ -296,7 +296,6 @@ static void udev_scan_class(struct list_for (dent =readdir (dir); dent !=NULL ; dent =readdir (dir)) {char dirname[PATH_SIZE ];DIR *dir2; -struct dirent *dent2;if (dent->d_name[0 ] =='.' )continue ;
@@ -306,6 +305,9 @@ static void udev_scan_class(struct list_ dir2 =opendir (dirname);if (dir2 !=NULL ) { +DIR *dir3; +struct dirent *dent2; +for (dent2 =readdir (dir2); dent2 !=NULL ; dent2 =readdir (dir2)) {char dirname2[PATH_SIZE ];
@@ -317,6 +319,25 @@ static void udev_scan_class(struct list_if (has_devt (dirname2) ||strcmp (dent->d_name,"net" ) ==0 )device_list_insert (dirname2, dent->d_name, device_list); + + dir3 =opendir (dirname2); +if (dir3 !=NULL ) { +struct dirent *dent3; + +for (dent3 =readdir (dir3); dent3 !=NULL ; dent3 =readdir (dir3)) { +char dirname3[PATH_SIZE ]; + +if (dent3->d_name[0 ] =='.' ) +continue ; + +snprintf (dirname3,sizeof (dirname3),"%s/%s" , dirname2, dent3->d_name); + dirname3[sizeof (dirname3)-1 ] ='\0' ; + +if (has_devt (dirname3)) +device_list_insert (dirname3, dent->d_name, device_list); + } +closedir (dir3); + } }closedir (dir2); }
PATCH 5/8 input: export input_dev_class so that input drivers can use it.
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
--- drivers/input/input.c | 3 ++- include/linux/input.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/input/input.c +2 -1
@@ -40,6 +40,7 @@ EXPORT_SYMBOL(input_accept_process);EXPORT_SYMBOL (input_flush_device);EXPORT_SYMBOL (input_event);EXPORT_SYMBOL (input_class); +EXPORT_SYMBOL_GPL (input_dev_class);#define INPUT_DEVICES 256
@@ -724,7 +725,7 @@ static void input_dev_release(struct clamodule_put (THIS_MODULE ); } -static struct class input_dev_class = { +struct class input_dev_class = { .name ="input_dev" , .release = input_dev_release, .class_dev_attrs = input_dev_attrs,
include/linux/input.h +1 -0
@@ -1075,6 +1075,7 @@ static inline void input_set_abs_params( }extern struct class *input_class; +extern struct class input_dev_class;#endif #endif
--
PATCH 6/8 input: move the input class devices under their new input_dev devices
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
--- drivers/input/evdev.c | 6 +++--- drivers/input/joydev.c | 6 +++--- drivers/input/mousedev.c | 10 +++++----- drivers/input/tsdev.c | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-)
drivers/input/mousedev.c +5 -5
@@ -648,9 +648,9 @@ static struct input_handle *mousedev_con mousedev_table[minor] = mousedev; -class_device_create (input_class,NULL , +class_device_create (&input_dev_class, &dev->cdev,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE + minor), - dev->dev,"mouse%d" , minor); + dev->cdev.dev,"mouse%d" , minor);return &mousedev->handle; }
@@ -660,7 +660,7 @@ static void mousedev_disconnect(struct istruct mousedev *mousedev = handle->private;struct mousedev_list *list; -class_device_destroy (input_class, +class_device_destroy (&input_dev_class,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist =0 ;
@@ -734,7 +734,7 @@ static int __init mousedev_init(void) mousedev_mix.exist =1 ; mousedev_mix.minor =MOUSEDEV_MIX ; -class_device_create (input_class,NULL , +class_device_create (&input_dev_class,NULL ,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE +MOUSEDEV_MIX ),NULL ,"mice" );#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -753,7 +753,7 @@ static void __exit mousedev_exit(void)if (psaux_registered)misc_deregister (&psaux_mouse);#endif -class_device_destroy (input_class, +class_device_destroy (&input_dev_class,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE +MOUSEDEV_MIX ));input_unregister_handler (&mousedev_handler); }
drivers/input/evdev.c +3 -3
@@ -686,9 +686,9 @@ static struct input_handle *evdev_connec evdev_table[minor] = evdev; -class_device_create (input_class,NULL , +class_device_create (&input_dev_class, &dev->cdev,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + minor), - dev->dev,"event%d" , minor); + dev->cdev.dev,"event%d" , minor);return &evdev->handle; }
@@ -698,7 +698,7 @@ static void evdev_disconnect(struct inpustruct evdev *evdev = handle->private;struct evdev_list *list; -class_device_destroy (input_class, +class_device_destroy (&input_dev_class,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + evdev->minor)); evdev->exist =0 ;
drivers/input/joydev.c +3 -3
@@ -513,9 +513,9 @@ static struct input_handle *joydev_conne joydev_table[minor] = joydev; -class_device_create (input_class,NULL , +class_device_create (&input_dev_class, &dev->cdev,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + minor), - dev->dev,"js%d" , minor); + dev->cdev.dev,"js%d" , minor);return &joydev->handle; }
@@ -525,7 +525,7 @@ static void joydev_disconnect(struct inpstruct joydev *joydev = handle->private;struct joydev_list *list; -class_device_destroy (input_class,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + joydev->minor)); +class_device_destroy (&input_dev_class,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist =0 ;if (joydev->open) {
drivers/input/tsdev.c +3 -3
@@ -409,9 +409,9 @@ static struct input_handle *tsdev_connec tsdev_table[minor] = tsdev; -class_device_create (input_class,NULL , +class_device_create (&input_dev_class, &dev->cdev,MKDEV (INPUT_MAJOR ,TSDEV_MINOR_BASE + minor), - dev->dev,"ts%d" , minor); + dev->cdev.dev,"ts%d" , minor);return &tsdev->handle; }
@@ -421,7 +421,7 @@ static void tsdev_disconnect(struct inpustruct tsdev *tsdev = handle->private;struct tsdev_list *list; -class_device_destroy (input_class, +class_device_destroy (&input_dev_class,MKDEV (INPUT_MAJOR ,TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist =0 ;
--
PATCH 7/8 input: remove the input_class structure, as it is unused.
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
--- drivers/input/input.c | 18 +++--------------- include/linux/input.h | 1 - 2 files changed, 3 insertions(+), 16 deletions(-)
drivers/input/input.c +3 -15
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(input_close_device);EXPORT_SYMBOL (input_accept_process);EXPORT_SYMBOL (input_flush_device);EXPORT_SYMBOL (input_event); -EXPORT_SYMBOL (input_class);EXPORT_SYMBOL_GPL (input_dev_class);#define INPUT_DEVICES 256
@@ -922,8 +921,6 @@ static struct file_operations input_fops .open = input_open_file, }; -struct class *input_class; -static int __init input_init (void ) {int err;
@@ -934,27 +931,19 @@ static int __init input_init(void)return err; } - input_class =class_create (THIS_MODULE ,"input" ); -if (IS_ERR (input_class)) { -printk (KERN_ERR "input: unable to register input class\n" ); - err =PTR_ERR (input_class); - goto fail1; - } - err =input_proc_init ();if (err) - goto fail2; + goto fail1; err =register_chrdev (INPUT_MAJOR ,"input" , &input_fops);if (err) {printk (KERN_ERR "input: unable to register char major %d" ,INPUT_MAJOR ); - goto fail3; + goto fail2; }return 0 ; - fail3:input_proc_exit (); - fail2:class_destroy (input_class); + fail2:input_proc_exit (); fail1:class_unregister (&input_dev_class);return err; }
@@ -963,7 +952,6 @@ static void __exit input_exit(void) {input_proc_exit ();unregister_chrdev (INPUT_MAJOR ,"input" ); -class_destroy (input_class);class_unregister (&input_dev_class); }
include/linux/input.h +0 -1
@@ -1074,7 +1074,6 @@ static inline void input_set_abs_params( dev->absbit[LONG(axis)] |= BIT(axis); } -extern struct class *input_class;extern struct class input_dev_class;#endif
--
PATCH 8/8 input: rename input_dev_class to input_class to be correct.
In reply to Greg KHFrom: Greg Kroah-Hartman <[email protected]>
--- drivers/input/evdev.c | 4 ++-- drivers/input/input.c | 14 +++++++------- drivers/input/joydev.c | 4 ++-- drivers/input/mousedev.c | 8 ++++---- drivers/input/tsdev.c | 4 ++-- include/linux/input.h | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-)
drivers/input/evdev.c +2 -2
@@ -686,7 +686,7 @@ static struct input_handle *evdev_connec evdev_table[minor] = evdev; -class_device_create (&input_dev_class, &dev->cdev, +class_device_create (&input_class, &dev->cdev,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + minor), dev->cdev.dev,"event%d" , minor);
@@ -698,7 +698,7 @@ static void evdev_disconnect(struct inpustruct evdev *evdev = handle->private;struct evdev_list *list; -class_device_destroy (&input_dev_class, +class_device_destroy (&input_class,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + evdev->minor)); evdev->exist =0 ;
drivers/input/input.c +7 -7
@@ -39,7 +39,7 @@ EXPORT_SYMBOL(input_close_device);EXPORT_SYMBOL (input_accept_process);EXPORT_SYMBOL (input_flush_device);EXPORT_SYMBOL (input_event); -EXPORT_SYMBOL_GPL (input_dev_class); +EXPORT_SYMBOL_GPL (input_class);#define INPUT_DEVICES 256
@@ -724,8 +724,8 @@ static void input_dev_release(struct clamodule_put (THIS_MODULE ); } -struct class input_dev_class = { - .name ="input_dev" , +struct class input_class = { + .name ="input" , .release = input_dev_release, .class_dev_attrs = input_dev_attrs, };
@@ -737,7 +737,7 @@ struct input_dev *input_allocate_device( dev =kzalloc (sizeof (struct input_dev ),GFP_KERNEL );if (dev) { dev->dynalloc =1 ; - dev->cdev.class = &input_dev_class; + dev->cdev.class = &input_class;class_device_initialize (&dev->cdev);INIT_LIST_HEAD (&dev->h_list);INIT_LIST_HEAD (&dev->node);
@@ -925,7 +925,7 @@ static int __init input_init(void) {int err; - err =class_register (&input_dev_class); + err =class_register (&input_class);if (err) {printk (KERN_ERR "input: unable to register input_dev class\n" );return err;
@@ -944,7 +944,7 @@ static int __init input_init(void)return 0 ; fail2:input_proc_exit (); - fail1:class_unregister (&input_dev_class); + fail1:class_unregister (&input_class);return err; }
@@ -952,7 +952,7 @@ static void __exit input_exit(void) {input_proc_exit ();unregister_chrdev (INPUT_MAJOR ,"input" ); -class_unregister (&input_dev_class); +class_unregister (&input_class); }subsys_initcall (input_init);
drivers/input/joydev.c +2 -2
@@ -513,7 +513,7 @@ static struct input_handle *joydev_conne joydev_table[minor] = joydev; -class_device_create (&input_dev_class, &dev->cdev, +class_device_create (&input_class, &dev->cdev,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + minor), dev->cdev.dev,"js%d" , minor);
@@ -525,7 +525,7 @@ static void joydev_disconnect(struct inpstruct joydev *joydev = handle->private;struct joydev_list *list; -class_device_destroy (&input_dev_class,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + joydev->minor)); +class_device_destroy (&input_class,MKDEV (INPUT_MAJOR ,JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist =0 ;if (joydev->open) {
drivers/input/mousedev.c +4 -4
@@ -648,7 +648,7 @@ static struct input_handle *mousedev_con mousedev_table[minor] = mousedev; -class_device_create (&input_dev_class, &dev->cdev, +class_device_create (&input_class, &dev->cdev,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE + minor), dev->cdev.dev,"mouse%d" , minor);
@@ -660,7 +660,7 @@ static void mousedev_disconnect(struct istruct mousedev *mousedev = handle->private;struct mousedev_list *list; -class_device_destroy (&input_dev_class, +class_device_destroy (&input_class,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist =0 ;
@@ -734,7 +734,7 @@ static int __init mousedev_init(void) mousedev_mix.exist =1 ; mousedev_mix.minor =MOUSEDEV_MIX ; -class_device_create (&input_dev_class,NULL , +class_device_create (&input_class,NULL ,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE +MOUSEDEV_MIX ),NULL ,"mice" );#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -753,7 +753,7 @@ static void __exit mousedev_exit(void)if (psaux_registered)misc_deregister (&psaux_mouse);#endif -class_device_destroy (&input_dev_class, +class_device_destroy (&input_class,MKDEV (INPUT_MAJOR ,MOUSEDEV_MINOR_BASE +MOUSEDEV_MIX ));input_unregister_handler (&mousedev_handler); }
drivers/input/tsdev.c +2 -2
@@ -409,7 +409,7 @@ static struct input_handle *tsdev_connec tsdev_table[minor] = tsdev; -class_device_create (&input_dev_class, &dev->cdev, +class_device_create (&input_class, &dev->cdev,MKDEV (INPUT_MAJOR ,TSDEV_MINOR_BASE + minor), dev->cdev.dev,"ts%d" , minor);
@@ -421,7 +421,7 @@ static void tsdev_disconnect(struct inpustruct tsdev *tsdev = handle->private;struct tsdev_list *list; -class_device_destroy (&input_dev_class, +class_device_destroy (&input_class,MKDEV (INPUT_MAJOR ,TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist =0 ;
include/linux/input.h +1 -1
@@ -1074,7 +1074,7 @@ static inline void input_set_abs_params( dev->absbit[LONG (axis)] |=BIT (axis); } -extern struct class input_dev_class; +extern struct class input_class;#endif #endif
--
Quoted 40 lines · Greg KH
Ok, finally. Here's a set of _working_ patches that properly implement nesting
class_devicestructures, and the follow-on patches to move the input subsystem to use them. Hotplug and release functions work properly now, and this will let us move/sys/block/to use class andclass_devicestructures soon.The input patches are on top of almost all of Dmitry's input patches. All of them are together in one series in my public patches at:
kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
and should show up in the next -mm release.The sysfs tree looks the same as it did last time, but now hotplug works properly for addition and removal, and we actually free the memory used :)
For those that don't remember, here's the sysfs tree on my desktop:
$ tree /sys/class/input/ -d /sys/class/input/ |-- input0 | |-- capabilities | |-- event0 | `-- id |-- input1 | |-- capabilities | |-- device -> ../../../devices/platform/i8042/serio1 | |-- event1 | | `-- device -> ../../../../devices/platform/i8042/serio1 | `-- id |-- input3 | |-- capabilities | |-- device -> ../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | |-- event2 | | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | |-- id | |-- mouse0 | | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | `-- ts0 | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 `-- mice
Quoted 6 lines
Ok, I think that covers everything.
Oh, one final thing. I really don't think that input should be a class. It looks like a "bus" and acts like a "bus" (you have different devices that have different drivers bind to them, and you want to load those drivers with the hotplug mechanism.)
[ Vojtech mumbles something about saying that from the beginning. ]
Quoted 4 lines
The only thing keeping this from
being a bus is the fact that we can't bind multiple drivers to a single device these days, and I can't see a way to move this code to that model, so oh well...
Oh, well.
Signature · 2 lines
Vojtech Pavlik SuSE Labs, SuSE CR
Dmitry Torokhov
maintainerQuoted 9 lines · Vojtech Pavlik
Quoted 5 lines · Greg KH
Oh, one final thing. I really don't think that input should be a class. It looks like a "bus" and acts like a "bus" (you have different devices that have different drivers bind to them, and you want to load those drivers with the hotplug mechanism.)
[ Vojtech mumbles something about saying that from the beginning. ]
I think Greg spoke a bit hastily here. Input_devs do not directly talk to the hardware and do not control power management and do not define access methods for the hardware therefore using bus abstraction would be wrong.
Quoted 5 lines
Quoted 4 lines
The only thing keeping this from
being a bus is the fact that we can't bind multiple drivers to a single device these days, and I can't see a way to move this code to that model, so oh well...
We should never let multiple drivers control the same piece of hardware (in all cases where you would you can always split that piece into smaller pieces, each controlled by its own driver). Input intrefaces, on the other hand, are not drivers in regular sense, they do not alter behavior of the underlying hardware. They just provide different "views"/interfaces for the same device and because they don't touch the hardware there can be many of them attached to the same device. This is the crucial difference between them and normal drivers.
--
Dmitry
Quoted 5 lines · Greg KH
Ok, finally. Here's a set of _working_ patches that properly implement nesting
class_devicestructures, and the follow-on patches to move the input subsystem to use them. Hotplug and release functions work properly now, and this will let us move/sys/block/to use class andclass_devicestructures soon.
Sorry, I completely changed my head about the "class nesting". I don't like it anymore and think it's a wrong design to spread fractions of the device relation tree over /sys/class. That breaks the whole idea of "class" to provide easy access to devices of the same kind.
Quoted 34 lines
The input patches are on top of almost all of Dmitry's input patches. All of them are together in one series in my public patches at:
kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
and should show up in the next -mm release.The sysfs tree looks the same as it did last time, but now hotplug works properly for addition and removal, and we actually free the memory used :)
For those that don't remember, here's the sysfs tree on my desktop:
$ tree /sys/class/input/ -d /sys/class/input/ |-- input0 | |-- capabilities | |-- event0 | `-- id |-- input1 | |-- capabilities | |-- device -> ../../../devices/platform/i8042/serio1 | |-- event1 | | `-- device -> ../../../../devices/platform/i8042/serio1 | `-- id |-- input3 | |-- capabilities | |-- device -> ../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | |-- event2 | | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | |-- id | |-- mouse0 | | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 | `-- ts0 | `-- device -> ../../../../devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0 `-- mice
Quoted 5 lines
To answer the remaining questions from the last thread:
Q: how are you going to determine what is really a
class_devand what
isn't, as there's no way to tell.
A: Who cares?
Me at least! :) As we can't distinguish between the type of class device which is nested. And that information is lost.
Quoted 5 lines
Seriously, tools like udev will watch for the "dev" file to be able create the required device node, and it will be the one getting the hotplug event. attribute groups do not generate hotplug events, and you should not be having a file called "dev" in your attribute group anyway.
Sure, that works for the "device node" case but stuff like HAL wants to build a meaningful tree from sysfs which does not only care about a "dev" file.
I looked at supporting stacked classes in HAL and that model doesn't fit.
Quoted 11 lines
Q: why does event2, mouse0, and input3 in the above tree all have the
same "device" symlink?
A: userspace tools expect that symlink there. They do not know that if
you traverse up a directory, and look at the symlink there, that's what the subdirectory points to too. That would be a mess. And, as those differentclass_devicestructures really are all bound to that same struct device, that is the proper representation of this.Q: How can you determine between input interfaces and input devices?
A: input devices have a "dev" file. And what really does userspace need
to know here?
Sure, we really need to know this! We could only hardcode names and match against this to get meaningful information out of that.
Quoted 4 lines
Q: Wait, what about nesting struct class instead? That would work,
right?
A: No, nesting classes is not going to happen. Classes are "major"
things, and aren't related to each other (well, some are by their
Quoted 8 lines
name only, like the different "scsi*" classes, but to the user, they are separate.)
Also, we can't emulate/sys/blockwith nested classes. And no, we can't change this to be/sys/class/block/partitionsand/sys/class/block/deviceswithout almost every sysfs user complaining loudly. That's not the real representation of the devices, and we need to really try to keep backward compatibility where we possibly can.
Well, actually this proposal creates two complete different class devices below one class. That may not be *implemented* as "class nesting", but it is *represented* as that to userspace.
I really think it is wrong to have the input hardware abstraction "input0" at the same level as "mice", which is a _completely_ different animal.
Quoted 1 line
Ok, I think that covers everything.
No, I really don't like that random mix of devices. A class is a simple collection of devices with the same interface and should never nest or combine different things.
Quoted 7 lines
Oh, one final thing. I really don't think that input should be a class. It looks like a "bus" and acts like a "bus" (you have different devices that have different drivers bind to them, and you want to load those drivers with the hotplug mechanism.) The only thing keeping this from being a bus is the fact that we can't bind multiple drivers to a single device these days, and I can't see a way to move this code to that model, so oh well...
The nesting classes implement a fraction of a device hierarchy in /sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?
Instead of that, I propose a unification of "/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.
We should model _all_ devices with its actual realationship in /sys/devices and /sys/class should only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of /sys/devices. All devices in /sys/class are only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.
/sys/class/block would look exactly like /sys/block today. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in /sys/class. The input devices are all clearly modeled in its hierarchy, in /sys/devices but we also get clean class interfaces:
/sys
|-- class | |-- block | | `-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda | |-- block_partition | | |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda1 | | `-- sda2 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda2 | |-- pci | | `-- 0000:00:1f.2 -> ../../devices/pci0000:00/0000:00:1f.2 | |-- input | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/mouse0 | | `-- event0 -> ../../devices/platform/i8042/serio0/event0 | |-- input_device | | `-- inputdev0 -> ../../devices/platform/i8042/serio0 | `-- tty | `-- console -> ../../devices/console | | |-- devices | |-- pci0000:00 | | `-- 0000:00:1f.2 | | |-- class -> ../../../class/pci | | |-- config | | |-- device | | |-- host0 | | | `-- target0:0:0 | | | |-- 0:0:0:0 | | | | |-- sda | | | | | |-- dev | | | | | |-- range | | | | | |-- removable | | | | | |-- sda1 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- sda2 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- size | | | | | `-- stat | | | | |-- delete | | | | |-- device_blocked | | | | |-- model | | | | |-- type | | | | `-- vendor | | | `-- power | | | `-- state | | |-- modalias | | |-- resource | | |-- subsystem_device | | |-- subsystem_vendor | | `-- vendor | |-- platform | | `-- i8042 | | |-- class -> ../../../class/platform | | `-- serio0 | | |-- event0 | | | `-- dev | | |-- mouse0 | | | `-- dev | | |-- bind_mode | | |-- class-> ../../../../class/serio | | |-- description | | |-- id | | | |-- extra | | | |-- id | | | |-- proto | | | `-- type | | |-- modalias | | |-- protocol | | |-- rate | | |-- resetafter | | `-- resolution | |-- mice | | `-- dev
...
Thanks,
Kay
Dmitry Torokhov
maintainerQuoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.
Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:
Hi,
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into /sys/devices hierarchy is the right solution either because one physical device could easily end up belonging to several classes. I recenty got an e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have /sys/class/net/interfaces and /sys/class/net/wireless /sys/class/net/irda, and /sys/class/net/wired subclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.
--
Dmitry
Am Do 13.10.2005 23:35 schrieb Dmitry Torokhov
<[email protected]>:
Quoted 2 lines · Kay Sievers
Quoted 1 line
[ ... ]
Quoted 6 lines
Quoted 6 lines
Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.
[ ... ]
Quoted 9 lines
Quoted 1 line
Hi,
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
Do not forget another side effect: we only have 'devices' within a tree under /sys/devices./sys/class is just a mapping with no real devices in them, only
symlinks.
So _everything_ can be found under /sys/devices, and you don't have to figure out whether this device your looking for is a class device or a proper device or whatever.
So we really have unified view for all devices, may they be physical or logical devices.
Quoted 10 lines
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes. I recenty got an e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.
But you can! That was the whole idea behind it.
Every device ends up in /sys/devices, and the class is just a 'view' on those devices.
(You might even call it API if you feel so inclined). /sys/class/net/interfaces would be implemented just as a collection of symlinks onto the proper devices in /sys/devices.
Overall this approach would make so many tasks so much simpler. We could figure out the dependencies on a given device by just following up the path; no need for the 'PHYSDEVPATH' stuff we have now for the events. Plus we could model weird things like the SCSI subsystem onto sysfs without having to resort to dirty tricks like we do now. Hell, we maybe can even map the OpenPROM device tree onto sysfs for all I know.
So it definitely looks far superior to what we have now.
Cheers,
Hannes
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:
Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.
Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.
That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
It invents artificial subclass names below a "master" class, which is absolutely not needed.
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!
I'm very sure, we want a unified tree in /sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.
Thanks,
Kay
Quoted 81 lines · Kay Sievers
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
It invents artificial subclass names below a "master" class, which is absolutely not needed.
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!
Quoted 6 lines
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.
Sorry, my previous drawing wasn't correct for the input devices.
Here is a new picture of the:
- all classes are unique and flat and will stay the same, even when the hierarchy of the devices changes
- all hierarchy is _only_ in /sys/devices
- virtual and physical devices are both in /sys/devices
proposal.
/sys
|-- class | |-- block | | `-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda | |-- block_partition | | |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda1 | | `-- sda2 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda2 | |-- pci | | `-- 0000:00:1f.2 -> ../../devices/pci0000:00/0000:00:1f.2 | |-- input | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/input0/mouse0 | | `-- event0 -> ../../devices/platform/i8042/serio0/input0/event0 | |-- input_device | | `-- input0 -> ../../devices/platform/i8042/serio0/input0 | `-- tty | `-- console -> ../../devices/console | | |-- devices | |-- pci0000:00 | | `-- 0000:00:1f.2 | | |-- class -> ../../../class/pci | | |-- config | | |-- device | | |-- host0 | | | `-- target0:0:0 | | | |-- 0:0:0:0 | | | | |-- sda | | | | | |-- dev | | | | | |-- range | | | | | |-- removable | | | | | |-- sda1 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- sda2 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- size | | | | | `-- stat | | | | |-- model | | | | |-- type | | | | `-- vendor | | | `-- power | | | `-- state | | |-- modalias | | |-- resource | | |-- subsystem_device | | |-- subsystem_vendor | | `-- vendor | |-- platform | | `-- i8042 | | `-- serio0 | | `-- input0 | | |-- event0 | | | `-- dev | | |-- mouse0 | | | `-- dev | | |-- bind_mode | | |-- description | | |-- id | | | |-- extra | | | |-- id | | | |-- proto | | | `-- type | | |-- modalias | | |-- protocol | | |-- rate | | |-- resetafter | | `-- resolution | |-- mice | | `-- dev
...
Thanks,
Kay
Quoted 174 lines · Kay Sievers
Quoted 81 lines · Kay Sievers
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
It invents artificial subclass names below a "master" class, which is absolutely not needed.
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!Quoted 6 lines
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.Sorry, my previous drawing wasn't correct for the input devices.
Here is a new picture of the:
- all classes are unique and flat and will stay the same, even when the hierarchy of the devices changes
- all hierarchy is _only_ in/sys/devices
- virtual and physical devices are both in/sys/devices
proposal./sys
|-- class | |-- block | | `-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda | |-- block_partition | | |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda1 | | `-- sda2 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda2 | |-- pci | | `-- 0000:00:1f.2 -> ../../devices/pci0000:00/0000:00:1f.2 | |-- input | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/input0/mouse0 | | `-- event0 -> ../../devices/platform/i8042/serio0/input0/event0 | |-- input_device | | `-- input0 -> ../../devices/platform/i8042/serio0/input0 | `-- tty | `-- console -> ../../devices/console | | |-- devices | |-- pci0000:00 | | `-- 0000:00:1f.2 | | |-- class -> ../../../class/pci | | |-- config | | |-- device | | |-- host0 | | | `-- target0:0:0 | | | |-- 0:0:0:0 | | | | |-- sda | | | | | |-- dev | | | | | |-- range | | | | | |-- removable | | | | | |-- sda1 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- sda2 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- size | | | | | `-- stat | | | | |-- model | | | | |-- type | | | | `-- vendor | | | `-- power | | | `-- state | | |-- modalias | | |-- resource | | |-- subsystem_device | | |-- subsystem_vendor | | `-- vendor | |-- platform | | `-- i8042 | | `-- serio0 | | `-- input0 | | |-- event0 | | | `-- dev | | |-- mouse0 | | | `-- dev | | |-- bind_mode | | |-- description | | |-- id | | | |-- extra | | | |-- id | | | |-- proto | | | `-- type | | |-- modalias | | |-- protocol | | |-- rate | | |-- resetafter | | `-- resolution | |-- mice | | `-- dev
Quoted 4 lines
...
Thanks,
Kay
I have a great deal of bad experience attempting to perform emergency mounts on Sun Workstations that have this same general scheme of un-typable:
../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda1
People need to enter this stuff without the help of cut-and-pase or even a back-space that works. Are you trying to replace "/dev/sda1" with the monster above? If so, you have way too much time on your hands.
Of course if this is just some more stuff to be bloated into the kernel and you don't even intend to use it, I shouldn't be concerned, should I? Just keep that stuff away from "/dev". We need to retain a sane interface.
Cheers,
Dick Johnson
Penguin : Linux version 2.6.13.4 on an i686 machine (5589.56 BogoMips). Warning : 98.36% of all statistics are fiction.
.
****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.
Thank you.
Quoted 186 lines · linux-os (Dick Johnson)
Quoted 174 lines · Kay Sievers
Quoted 81 lines · Kay Sievers
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
It invents artificial subclass names below a "master" class, which is absolutely not needed.
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!Quoted 6 lines
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.Sorry, my previous drawing wasn't correct for the input devices.
Here is a new picture of the:
- all classes are unique and flat and will stay the same, even when the hierarchy of the devices changes
- all hierarchy is _only_ in/sys/devices
- virtual and physical devices are both in/sys/devices
proposal./sys
|-- class | |-- block | | `-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda | |-- block_partition | | |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda1 | | `-- sda2 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda2 | |-- pci | | `-- 0000:00:1f.2 -> ../../devices/pci0000:00/0000:00:1f.2 | |-- input | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/input0/mouse0 | | `-- event0 -> ../../devices/platform/i8042/serio0/input0/event0 | |-- input_device | | `-- input0 -> ../../devices/platform/i8042/serio0/input0 | `-- tty | `-- console -> ../../devices/console | | |-- devices | |-- pci0000:00 | | `-- 0000:00:1f.2 | | |-- class -> ../../../class/pci | | |-- config | | |-- device | | |-- host0 | | | `-- target0:0:0 | | | |-- 0:0:0:0 | | | | |-- sda | | | | | |-- dev | | | | | |-- range | | | | | |-- removable | | | | | |-- sda1 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- sda2 | | | | | | |-- dev | | | | | | |-- size | | | | | | |-- start | | | | | | `-- stat | | | | | |-- size | | | | | `-- stat | | | | |-- model | | | | |-- type | | | | `-- vendor | | | `-- power | | | `-- state | | |-- modalias | | |-- resource | | |-- subsystem_device | | |-- subsystem_vendor | | `-- vendor | |-- platform | | `-- i8042 | | `-- serio0 | | `-- input0 | | |-- event0 | | | `-- dev | | |-- mouse0 | | | `-- dev | | |-- bind_mode | | |-- description | | |-- id | | | |-- extra | | | |-- id | | | |-- proto | | | `-- type | | |-- modalias | | |-- protocol | | |-- rate | | |-- resetafter | | `-- resolution | |-- mice | | `-- devQuoted 4 lines
...
Thanks,
KayI have a great deal of bad experience attempting to perform emergency mounts on Sun Workstations that have this same general scheme of un-typable:
Quoted 6 lines
../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sda/sda1
People need to enter this stuff without the help of cut-and-pase or even a back-space that works. Are you trying to replace "
/dev/sda1" with the monster above? If so, you have way too much time on your hands.
Welcome to Linux!
Sysfs was never and will not be involved with mounting or device nodes!
Kay
Quoted 8 lines · Kay Sievers
Sorry, my previous drawing wasn't correct for the input devices.
Here is a new picture of the:
- all classes are unique and flat and will stay the same, even when the hierarchy of the devices changes
- all hierarchy is _only_ in/sys/devices
- virtual and physical devices are both in/sys/devices
proposal.
I like the layout.
I'm not completely sure whether mouse0 and event0 are the same class, because they have different APIs and protocols. And I believe that class is exactly that - a collection of devices where you can use the same API to access them. A possibility would be to do it like this:
Quoted 11 lines
/sys
|-- class | |-- mouse | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/input0/mouse0 | |---event | | `-- event0 -> ../../devices/platform/i8042/serio0/input0/event0 | |-- input | | `-- input0 -> ../../devices/platform/i8042/serio0/input0 | `-- tty | `-- console -> ../../devices/console
It might be too much work to create a new class in each of the handlers, it'd be similar to harddrives and partititions having different classes.
Quoted 24 lines
/sys
|-- class | |-- input | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/input0/mouse0 | | `-- event0 -> ../../devices/platform/i8042/serio0/input0/event0 | |-- input_device | | `-- input0 -> ../../devices/platform/i8042/serio0/input0 | |-- devices | |-- platform | | `-- i8042 | | `-- serio0 | | `-- input0 | | |-- event0 | | | `-- dev | | |-- mouse0 | | | `-- dev | | |-- bind_mode | | |-- description | | |-- id | | | |-- extra | | | |-- id | | | |-- proto
Quoted 8 lines
| | | `-- type | | |-- modalias | | |-- protocol | | |-- rate | | |-- resetafter | | `-- resolution | |-- mice | | `-- dev
Having 'mice' at top level is not very nice. It's a logical consequence of the system, and as such probably correct, though.
Signature · 2 lines
Vojtech Pavlik SuSE Labs, SuSE CR
Quoted 30 lines · Vojtech Pavlik
Quoted 8 lines · Kay Sievers
Sorry, my previous drawing wasn't correct for the input devices.
Here is a new picture of the:
- all classes are unique and flat and will stay the same, even when the hierarchy of the devices changes
- all hierarchy is _only_ in/sys/devices
- virtual and physical devices are both in/sys/devices
proposal.I like the layout.
I'm not completely sure whether mouse0 and event0 are the same class, because they have different APIs and protocols. And I believe that class is exactly that - a collection of devices where you can use the same API to access them. A possibility would be to do it like this:
Quoted 11 lines
/sys
|-- class | |-- mouse | | |-- mice -> ../../devices/mice | | |-- mouse0 -> ../../devices/platform/i8042/serio0/input0/mouse0 | |---event | | `-- event0 -> ../../devices/platform/i8042/serio0/input0/event0 | |-- input | | `-- input0 -> ../../devices/platform/i8042/serio0/input0 | `-- tty | `-- console -> ../../devices/console
Quoted 4 lines
It might be too much work to create a new class in each of the handlers, it'd be similar to harddrives and partititions having different classes.
This illustrates the problem I have with flat classification: "event" is way too generic name and "input_event", "input_mouse", etc. is way too ugly. "input/event", "input/mouse" is much better IMO.
Signature · 1 line
Dmitry
Dmitry Torokhov
maintainerQuoted 54 lines · Kay Sievers
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.
Quoted 4 lines
That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
Does anyone know how many of these we have? We are moving /sys/block to /sys/class so many of these will require upgrades anyway. Could libsysfs hide some of the changes? I have not looked at libsysfs at all though...
Btw, is your proposal with moving it all into /sys/device less drastic?
Quoted 3 lines
It invents artificial subclass names below a "master" class, which is absolutely not needed.
I really do not see why you think that "ieee1394_node" and "ieee1394_transport" are natural names while "ieee1394/node" and "ieee1394/transport" are "artificial".
Quoted 3 lines
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
Why is "interfaces" is more magic than "wireless"? Is it just the name that is confusing? We could call it "netifs", "netdevs", "devices" - just pick a name you like better.
Quoted 9 lines
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
Well, it is rather simple I think - if it works with hardware and needs power management then it's a physical device. If it just a kernel abstraction/API for group of similar objects then it is a class device. Physical device can only have one driver, class device can have several interfaces/views. So far we have input interfaces and SCSI generic interface.
Quoted 3 lines
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
Could you tell me which ones you consider virtual buses?
Quoted 5 lines
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!
Quoted 7 lines
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.
Having hierarchy in the /sys/devices is nice and I think I agree with it. I don't think it will reslve any confusion for the coder WRT physical/virtual devices - after all I think you just need to change class_device kset from class's to devices and that will "move" the object into the new spot in /sys tree.
However having class hierarchy spelled out is also nice because it _does exist_. Right now we just encode it with common prefixes in the class names.
--
Dmitry
Quoted 55 lines · Dmitry Torokhov
Quoted 54 lines · Kay Sievers
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.
Quoted 6 lines
Quoted 4 lines
That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
Does anyone know how many of these we have?
A lot! From general distro specific system-management to subsystem specific setup tools and tons of udev rules... There is definitely no chance to break /sys/class in _all_ subsystems by introducing subdirectories.
Quoted 2 lines
We are moving
/sys/block
to/sys/classso many of these will require upgrades anyway.
If needed, there can be a link from /sys/block to /sys/class/block and it will look exactly like is is today.
Quoted 1 line
Could libsysfs hide some of the changes?
Not without hardcoding susbsystem-specific knowledge/translation into it, which will not happen and will be definitely the wrong way to solve such a thing. Only the block-move case could be easily covered by libsysfs as it is already prepared to do this and "block" is a "class" from the first version of libsysfs on.
Quoted 1 line
Btw, is your proposal with moving it all into
/sys/deviceless drastic?
Definitely, cause it keeps all the curent api! The only difference is that class-devices are reached by symlinks instead of real directories. The pathes to the devices are the same!
Quoted 7 lines
Quoted 3 lines
It invents artificial subclass names below a "master" class, which is absolutely not needed.
I really do not see why you think that "
ieee1394_node" and "ieee1394_transport" are natural names while "ieee1394/node" and "ieee1394/transport" are "artificial".
Well, all three classes are different kind of devices. All devices are at the same level, which I absolutely like. You propose an artificial "hierarchy of classes" or a "superclass", which will break everything and give us no advantage, I think.
Quoted 7 lines
Quoted 3 lines
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
Why is "interfaces" is more magic than "wireless"? Is it just the name that is confusing? We could call it "netifs", "netdevs", "devices" - just pick a name you like better.
Cause "interfaces" is a classification by itself and this is wrong! If you give one of your "subclass devices" an interface, let's say "input0" will get a device node to talk to the low-level device, where do you want to stick it then? You will move the device around to the "interface" directory? That breaks the api!
Take a step back and look what a kernel interface is about. It is to give userland a unified view to devices. The internal kernel structure like "bus", "class", "bus_device", "class_device" are in no way interesting for userspace. It's a kernel implementation detail.
All we want are DEVICES! And from devices we want:
- a classification: /sys/class/<name>
- the properties: attribute files to read values or to invoke actions
- the dependency tree: /sys/devices/<device1>/<device2>
Any mix between any of the three things is completely wrong, makes it hard to read and can never provide a stable device interface.
In HAL, which is the heaviest user of sysfs today, we need to reconstruct the device tree by following the "device" symlink from sysfs to get a unified tree and use the class name to classify the device properly.
In udevd I need to read PHYSDEVPATH to ensure the right event order. All that is needed cause the _internal_ kernel structure is exported, which is "broken" in the sense of a unified device interface.
Both proposals, the subclasses and also the stacked class-devices will render it even more "broken" by mixing classification and device pathes.
Quoted 5 lines
Quoted 5 lines
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
Quoted 7 lines
Quoted 4 lines
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
Well, it is rather simple I think - if it works with hardware and needs power management then it's a physical device.
Forget power management and /sys/devices. The PM guys say, that they will need their own tree for this. Anyway, sticking virtual devices in the tree, but keep the hierarchy is not a reason not to be able to walk up the chain and change device state (We already have a lot non-hardware devices in /sys/devices). You will get the type of device by looking which class it belongs to.
The distinction between "virtual" and "physical" does not make any sense for userspace! And it will get more complicated every year with every new virtualization or abstract subsystem.
Quoted 5 lines
If it just a
kernel abstraction/API for group of similar objects then it is a class device. Physical device can only have one driver, class device can have several interfaces/views. So far we have input interfaces and SCSI generic interface.
That is a kernel implementation detail, we really don't care from userspace. Rememer, sysfs is a _userspace_ interface!
Quoted 5 lines
Quoted 3 lines
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
Could you tell me which ones you consider virtual buses?
acpi-bus, serial-bus, scsi-target-bus, platform-bus, ... SUSE had an input-bus, ... These all exist cause of the stupid "virtual" - "physical" distinction. XEN has it's own xen-bus, and absolutely _no_ physical hardware is involved...
Quoted 13 lines
Quoted 5 lines
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!
Quoted 7 lines
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.
Quoted 5 lines
Having hierarchy in the
/sys/devicesis nice and I think I agree with it. I don't think it will reslve any confusion for the coder WRT physical/virtual devices - after all I think you just need to changeclass_devicekset from class's to devices and that will "move" the object into the new spot in /sys tree.
What we really need is to keep "hierarchy" and "classification" separated. /sys/class is our usual interface to the kernel devices and we don't want to stick hierarchy here. All hierarchy belongs into a single place with all parent-less devices in the root. That way we can move devices around in the hierarchy if we need to change kernel device handling. But the most important reason: it will always keep the class interface to the devices stable!
Think of sticking an "abstraction device" into a subsystem, like "input0" is, only with a flat class interface you can do this without breaking the users interface. (It already happened several times with scsi.)
Quoted 3 lines
However having class hierarchy spelled out is also nice because it
_doesexist_. Right now we just encode it with common prefixes in the class names.
That is "grouping", it does not expose any hierarchy. And again, creating tons of sysmlinks between class-devices like in your input proposal, is wrong I think.
Thanks,
Kay
Quoted 8 lines · Kay Sievers
Quoted 2 lines · Dmitry Torokhov
Does anyone know how many of these we have?
A lot! From general distro specific system-management to subsystem specific setup tools and tons of udev rules... There is definitely no chance to break
/sys/classin _all_ subsystems by introducing subdirectories.
Quoted 6 lines
Quoted 2 lines
We are moving
/sys/block
to/sys/classso many of these will require upgrades anyway.If needed, there can be a link from
/sys/blockto/sys/class/blockand it will look exactly like is is today.
We could also add links in the form of:
/sys/class/<subsystem>/<nested_class> -> /sys/class/<subsystem>_<nested_class>
to keep compatibility with nested classes too to give userspace a chance to catch up...
Quoted 8 lines
Quoted 1 line
Could libsysfs hide some of the changes?
Not without hardcoding susbsystem-specific knowledge/translation into it, which will not happen and will be definitely the wrong way to solve such a thing. Only the block-move case could be easily covered by libsysfs as it is already prepared to do this and "block" is a "class" from the first version of libsysfs on.
OK..
Quoted 6 lines
Quoted 1 line
Btw, is your proposal with moving it all into
/sys/deviceless drastic?Definitely, cause it keeps all the curent api! The only difference is that class-devices are reached by symlinks instead of real directories. The pathes to the devices are the same!
OK..
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
It invents artificial subclass names below a "master" class, which is absolutely not needed.
Quoted 9 lines
Quoted 3 lines
I really do not see why you think that "
ieee1394_node" and "ieee1394_transport" are natural names while "ieee1394/node" and "ieee1394/transport" are "artificial".Well, all three classes are different kind of devices. All devices are at the same level, which I absolutely like. You propose an artificial "hierarchy of classes" or a "superclass", which will break everything and give us no advantage, I think.
Call it "subsystem" actually.
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
Why is "interfaces" is more magic than "wireless"? Is it just the name that is confusing? We could call it "netifs", "netdevs", "devices" - just pick a name you like better.
Quoted 6 lines
Cause "interfaces" is a classification by itself and this is wrong! If you give one of your "subclass devices" an interface, let's say "input0" will get a device node to talk to the low-level device, where do you want to stick it then? You will move the device around to the "interface" directory? That breaks the api!
No, not at all. The input0 will get a new interface, blahdevX, exactly like eventX, mouseX, jsX, tsX, etc. and it will go into "interfaces". input0 itself will stay in /sys/class/input/devices.
Quoted 5 lines
Take a step back and look what a kernel interface is about. It is to give userland a unified view to devices. The internal kernel structure like "bus", "class", "
bus_device", "class_device" are in no way interesting for userspace. It's a kernel implementation detail.
Quoted 7 lines
All we want are DEVICES! And from devices we want:
- a classification: /sys/class/<name>
- the properties: attribute files to read values or to invoke actions
- the dependency tree: /sys/devices/<device1>/<device2>
Any mix between any of the three things is completely wrong, makes it hard to read and can never provide a stable device interface.
Yes, I agree that we should have device tree in /sys/devices. But I do not think that flat classification is sufficient. Right now it is not enough and we compensate for it with names.
Signature · 1 line
Dmitry
Quoted 3 lines · Kay Sievers
A lot! From general distro specific system-management to subsystem specific setup tools and tons of udev rules... There is definitely no chance to break
/sys/classin _all_ subsystems by introducing subdirectories.
I agree.
Quoted 5 lines
Quoted 1 line
Btw, is your proposal with moving it all into
/sys/deviceless drastic?Definitely, cause it keeps all the curent api! The only difference is that class-devices are reached by symlinks instead of real directories. The pathes to the devices are the same!
Ok, I've spent a while thinking about this proposal and originally I thought it was the same thing we had heard years ago. But I was wrong, moving the class stuff into the device tree is the right thing to do, as long as we keep them as new "things" in the tree (previous proposals just had the /sys/class stuff as symlinks pointing to the devices themselves, which would not work for a range of reasons.)
So, what to do now? Here's my proposal for the future.
We figure out some way to agree on the input stuff, using class_device and get that into 2.6.15. Personally, I like the stuff I just did and is in the -mm tree :)
But, if you think we can't break userspace by adding nested class devices just yet, I agree, and can probably just put a symlink in /sys/class/input to the nested devices, which will make everything "just work". I'll try that out later tonight and let you all know how it goes.
Then, we move the class stuff into real devices. There was always a lot of duplication with the class and device code, and this shows that there is a commonality there. At the same time, I'll work on making the attribute stuff easier and possibly merge the kobject and device structures together a bit (possibly I said, I don't know quite how much yet...)
But this second step is going to take a while, have to not break everything along the way, and should hopefully clean up a lot of mess tht the current driver core has. I'd be glad to do it :)
Acceptable to everyone?
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
thanks,
greg k-h
p.s. Kay, that's the last time I mention to you that I didn't know what I would be working on for the next few months...
Dmitry Torokhov
maintainerQuoted 6 lines · Greg KH
So, what to do now? Here's my proposal for the future.
We figure out some way to agree on the input stuff, using
class_deviceand get that into 2.6.15. Personally, I like the stuff I just did and is in the -mm tree :)
If we are shooting at 2.6.15 I would just go with original 2-class solution (input and input_dev) with doing symlinks in form of /sys/class/input/mouseX/device -> /sys/class/input_dev/inputX
Correct me if I am wrong but this is least invasive and (at least for older hotplug installations) all that is needed to make it work is a symlink from input.agent to input_dev.agent.
--
Dmitry
Quoted 12 lines · Dmitry Torokhov
Quoted 6 lines · Greg KH
So, what to do now? Here's my proposal for the future.
We figure out some way to agree on the input stuff, using
class_deviceand get that into 2.6.15. Personally, I like the stuff I just did and is in the -mm tree :)If we are shooting at 2.6.15 I would just go with original 2-class solution (input and
input_dev) with doing symlinks in form of/sys/class/input/mouseX/device->/sys/class/input_dev/inputX
Quoted 6 lines
Correct me if I am wrong but this is least invasive and (at least for older hotplug installations) all that is needed to make it work is a symlink from input.agent to input_dev.agent.
--
Dmitry
I'm not sure if we want to introduce an incorrect change to the sysfs topology only to remove it in the next release. Currently, class devices are not expected to link between one another.
Thanks,
Adam
Quoted 9 lines · Adam Belay
Quoted 8 lines · Dmitry Torokhov
Quoted 6 lines · Greg KH
So, what to do now? Here's my proposal for the future.
We figure out some way to agree on the input stuff, using
class_deviceand get that into 2.6.15. Personally, I like the stuff I just did and is in the -mm tree :)
Quoted 7 lines
Quoted 7 lines
If we are shooting at 2.6.15 I would just go with original 2-class solution (input and
input_dev) with doing symlinks in form of/sys/class/input/mouseX/device->/sys/class/input_dev/inputXCorrect me if I am wrong but this is least invasive and (at least for older hotplug installations) all that is needed to make it work is a symlink from input.agent to input_dev.agent.
Yes, it is almost compatible with the "old" hotplug. On modern setups it is just one udev rule to catch the right event. On older setups a simple symlink should work, yes.
Quoted 3 lines
I'm not sure if we want to introduce an incorrect change to the sysfs topology only to remove it in the next release. Currently, class devices are not expected to link between one another.
The easiest would be to leave the "device"-link in its current state:
mouse0 -> ../../../devices/...
and correct that later by getting completely rid of _all_ "device" links with the move of the device object to /sys/devices/ (the DEVPATH for "mouse0" will then contain the _complete_ hierarchy including "input0").
Current userspace is not aware to follow two "device" links. Should not be hard to implement, but seems not really worth the effort, if we plan to rearrange it to a global device tree anyway.
Thanks,
Kay
Quoted 39 lines · Greg KH
Quoted 3 lines · Kay Sievers
A lot! From general distro specific system-management to subsystem specific setup tools and tons of udev rules... There is definitely no chance to break
/sys/classin _all_ subsystems by introducing subdirectories.I agree.
Quoted 5 lines
Quoted 1 line
Btw, is your proposal with moving it all into
/sys/deviceless drastic?Definitely, cause it keeps all the curent api! The only difference is that class-devices are reached by symlinks instead of real directories. The pathes to the devices are the same!
Ok, I've spent a while thinking about this proposal and originally I thought it was the same thing we had heard years ago. But I was wrong, moving the class stuff into the device tree is the right thing to do, as long as we keep them as new "things" in the tree (previous proposals just had the
/sys/classstuff as symlinks pointing to the devices themselves, which would not work for a range of reasons.)So, what to do now? Here's my proposal for the future.
We figure out some way to agree on the input stuff, using
class_deviceand get that into 2.6.15. Personally, I like the stuff I just did and is in the -mm tree :)But, if you think we can't break userspace by adding nested class devices just yet, I agree, and can probably just put a symlink in
/sys/class/inputto the nested devices, which will make everything "just work". I'll try that out later tonight and let you all know how it goes.Then, we move the class stuff into real devices. There was always a lot of duplication with the class and device code, and this shows that there is a commonality there. At the same time, I'll work on making the attribute stuff easier and possibly merge the kobject and device structures together a bit (possibly I said, I don't know quite how much yet...)
Quoted 5 lines
But this second step is going to take a while, have to not break everything along the way, and should hopefully clean up a lot of mess tht the current driver core has. I'd be glad to do it :)
Acceptable to everyone?
Sounds good to me. The changes to driver model internals may be substantial. For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
It also may make sense to move bus_types to the "class" interface. The layered classes suggestion is especially useful here because we can have a "hardware" or "bus" class that acts as a parent for "pci", "usb", etc.
Also, we could make driver objects a "class" and represent them in the global device tree, giving each driver instance its own unique namespace.
Quoted 5 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree. If the device doesn't have any parents or dependencies, then that's logically where it belongs.
Thanks,
Adam
Quoted 33 lines · Adam Belay
Quoted 32 lines · Greg KH
Quoted 3 lines · Kay Sievers
A lot! From general distro specific system-management to subsystem specific setup tools and tons of udev rules... There is definitely no chance to break
/sys/classin _all_ subsystems by introducing subdirectories.I agree.
Quoted 5 lines
Quoted 1 line
Btw, is your proposal with moving it all into
/sys/deviceless drastic?Definitely, cause it keeps all the curent api! The only difference is that class-devices are reached by symlinks instead of real directories. The pathes to the devices are the same!
Ok, I've spent a while thinking about this proposal and originally I thought it was the same thing we had heard years ago. But I was wrong, moving the class stuff into the device tree is the right thing to do, as long as we keep them as new "things" in the tree (previous proposals just had the
/sys/classstuff as symlinks pointing to the devices themselves, which would not work for a range of reasons.)So, what to do now? Here's my proposal for the future.
We figure out some way to agree on the input stuff, using
class_deviceand get that into 2.6.15. Personally, I like the stuff I just did and is in the -mm tree :)But, if you think we can't break userspace by adding nested class devices just yet, I agree, and can probably just put a symlink in
/sys/class/inputto the nested devices, which will make everything "just work". I'll try that out later tonight and let you all know how it goes.
Quoted 6 lines
Quoted 6 lines
Then, we move the class stuff into real devices. There was always a lot of duplication with the class and device code, and this shows that there is a commonality there. At the same time, I'll work on making the attribute stuff easier and possibly merge the kobject and device structures together a bit (possibly I said, I don't know quite how much yet...)
Yeah, would be nice if we can share the attribute define/create/grouping stuff over all devices. Currently we have device/class/block attribute management which are all do almost the same.
Quoted 7 lines
Quoted 5 lines
But this second step is going to take a while, have to not break everything along the way, and should hopefully clean up a lot of mess tht the current driver core has. I'd be glad to do it :)
Acceptable to everyone?
Sounds good to me. The changes to driver model internals may be substantial.
Sounds very good to me too. :)
I like to see the "dynamic input" as soon as possible in the tree, as I'm waiting for more than a year now to get rid of the old stuff in udev only kept there for "input". :)
/sys/class/input/ and /sys/class/input_device/ and a matching SUBSYSTEM value would be the easiest for userspace without much breakage involved. That would give us a /sbin/hotplug-fork free driver core and we can start rearranging stuff.
Quoted 5 lines
For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
We should try this, it feels like "buses" can easily become "classes", like the SUBSYSTEM value already looks these days. We'll see...
Quoted 13 lines
It also may make sense to move
bus_typesto the "class" interface. The layered classes suggestion is especially useful here because we can have a "hardware" or "bus" class that acts as a parent for "pci", "usb", etc.Also, we could make driver objects a "class" and represent them in the global device tree, giving each driver instance its own unique namespace.
Quoted 5 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
Quoted 4 lines
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree. If the device doesn't have any parents or dependencies, then that's logically where it belongs.
We do the same in HAL every unconnected object just lives in the root of the device tree.
Thanks,
Kay
Quoted 7 lines · Adam Belay
Sounds good to me. The changes to driver model internals may be substantial. For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
That's a bus, not a class device. Drivers bind to devices through a bus. That's why we have busses.
Quoted 3 lines
It also may make sense to move
bus_typesto the "class" interface. The layered classes suggestion is especially useful here because we can have a "hardware" or "bus" class that acts as a parent for "pci", "usb", etc.
Hm, I don't really know...
Quoted 2 lines
Also, we could make driver objects a "class" and represent them in the global device tree, giving each driver instance its own unique namespace.
Huh? How would you do that? Also, we really don't have different driver "instances", so trying to represent something like that in sysfs would probably be more work than it's worth.
Quoted 8 lines
Quoted 4 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree.
Everything that's currently a platform device go to the root? No, that's not going to happen, sorry.
Quoted 2 lines
If the device doesn't have any parents or dependencies, then that's logically where it belongs.
We do have a real platform "bus" that devices hang off of. Where else is that keyboard controller at :)
thanks,
greg k-h
Quoted 11 lines · Greg KH
Quoted 7 lines · Adam Belay
Sounds good to me. The changes to driver model internals may be substantial. For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
That's a bus, not a class device. Drivers bind to devices through a bus. That's why we have busses.
If class devices and devices belong in the same tree, then clearly the original distinction is artificial. "struct bus_type" is a class of "struct device". "struct class" is a class of "struct class_dev". We now know of devices in between these two extremes (e.g. pci express port driver). It's also possible that drivers will want to bind to class devices (e.g. a partition driver binding to a block device). Isn't it fair to say that the "bus_type" vs. "class" distinction is also artificial? At the very least they are duplicating some code.
Quoted 7 lines
Quoted 3 lines
Also, we could make driver objects a "class" and represent them in the global device tree, giving each driver instance its own unique namespace.
Huh? How would you do that? Also, we really don't have different driver "instances", so trying to represent something like that in sysfs would probably be more work than it's worth.
(all in same tree)
pci0000:00.00 <- physical device
|
\- e1000:0 <- driver
|
\- eth0 <- class device
We already informally have driver instances. They're pointed to in "driver_data".
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
Quoted 6 lines
Quoted 3 lines
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree.
Everything that's currently a platform device go to the root? No, that's not going to happen, sorry.
Not at all. Rather, everything that's currently a platform device goes to where it actually belongs in the device tree. ACPI (and other firmware) enumerates all of these devices. They're generally children of LPCs and ISA bridges. Making a special exception for these devices is ugly when we can easily represent them like every other device. This will even be possible without ACPI for many of these devices if we create an "ISA" bus driver abstraction.
The main point here is that "platform" is really a hack to represent primitive physical devices that don't fit well into the driver model. There may be better ways of approaching this problem.
Quoted 6 lines
Quoted 3 lines
If the device doesn't have any parents or dependencies, then that's logically where it belongs.
We do have a real platform "bus" that devices hang off of. Where else is that keyboard controller at :)
As stated above, the keyboard actually does have a real location to hang off of. Nonetheless, a keyboard controller is a physical device. It's very different from a "virtual device" like a tty. Therefore, it seems unreasonable to make virtual devices belong to the "platform" bus.
If a device doesn't have a parent device, it belongs at the root of the tree. That's the only obvious way to represent such a lack of dependency. This applies to both class and physical devices.
Thanks,
Adam
Quoted 8 lines · Adam Belay
As stated above, the keyboard actually does have a real location to hang off of. Nonetheless, a keyboard controller is a physical device. It's very different from a "virtual device" like a tty. Therefore, it seems unreasonable to make virtual devices belong to the "platform" bus.
If a device doesn't have a parent device, it belongs at the root of the tree. That's the only obvious way to represent such a lack of dependency. This applies to both class and physical devices.
Well, a VT is obviously a child of the graphics card and of the keyboard. Similarly for the 'mice' device, which is a child of all input devices that offer mouseying capabilities.
It's just impossible to express in a tree.
Signature · 2 lines
Vojtech Pavlik SuSE Labs, SuSE CR
Quoted 13 lines · Adam Belay
Quoted 11 lines · Greg KH
Quoted 7 lines · Adam Belay
Sounds good to me. The changes to driver model internals may be substantial. For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
That's a bus, not a class device. Drivers bind to devices through a bus. That's why we have busses.
Quoted 8 lines
If class devices and devices belong in the same tree, then clearly the original distinction is artificial. "struct
bus_type" is a class of "struct device". "struct class" is a class of "structclass_dev". We now know of devices in between these two extremes (e.g. pci express port driver). It's also possible that drivers will want to bind to class devices (e.g. a partition driver binding to a block device). Isn't it fair to say that the "bus_type" vs. "class" distinction is also artificial? At the very least they are duplicating some code.
I agree and would like to see the "bus" functionality just as set of special methods of a unified device struture also used for class devices.
Quoted 11 lines
Quoted 11 lines
Quoted 8 lines
Quoted 4 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree.
Everything that's currently a platform device go to the root? No, that's not going to happen, sorry.
But will sticking stuff like "mice" or "tty" into "platform" will really work? These devices belong to their own primary class like "input" or "tty" and they can not be part of a "bus" at the same time, right?
I'm dreaming of:
- merging "struct device" and "struct class_device"
- provide current "bus" and "class" methodes for _all_ devices
- every current "bus", just becomes a "class" to indicate a group of devices, where "input" has the same "group interface" in /sys/class/ as "pci" - buses go away completely
- every device is a member of one single class, be it a pci-bus-device or a virtual class
- separate strictly between hierarchy and classification, which is a bit ugly sometimes cause of the flat class layout, but it provides a very nice way to keep the class interface simple and therefore stable, while still be able to change the device hierarchy
- /sys/devices becomes a buch of trees and some parent-less devices in the root, its whole reason is just to export the device dependency structure, nothing else
That way the "platform bus" would be a "platform class", which will only contain devices which are not part of any other class. All these parent-less devices would live in the root of /sys/devices to reflect their lack of dependency.
Things like "tty" and "mice", would be members of their natural class, but also live in the root of /sys/devices. That way we have the technically correct classifcation and hierarchy.
Does that make sense?
Thanks,
Kay
Dmitry Torokhov
maintainerQuoted 38 lines · Kay Sievers
Quoted 13 lines · Adam Belay
Quoted 11 lines · Greg KH
Quoted 7 lines · Adam Belay
Sounds good to me. The changes to driver model internals may be substantial. For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
That's a bus, not a class device. Drivers bind to devices through a bus. That's why we have busses.
Quoted 8 lines
If class devices and devices belong in the same tree, then clearly the original distinction is artificial. "struct
bus_type" is a class of "struct device". "struct class" is a class of "structclass_dev". We now know of devices in between these two extremes (e.g. pci express port driver). It's also possible that drivers will want to bind to class devices (e.g. a partition driver binding to a block device). Isn't it fair to say that the "bus_type" vs. "class" distinction is also artificial? At the very least they are duplicating some code.I agree and would like to see the "bus" functionality just as set of special methods of a unified device struture also used for class devices.
Quoted 11 lines
Quoted 11 lines
Quoted 8 lines
Quoted 4 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree.
Everything that's currently a platform device go to the root? No, that's not going to happen, sorry.
Quoted 9 lines
But will sticking stuff like "mice" or "tty" into "platform" will really work? These devices belong to their own primary class like "input" or "tty" and they can not be part of a "bus" at the same time, right?
I'm dreaming of:
- merging "struct device" and "structclass_device"- provide current "bus" and "class" methodes for _all_ devices
This way you are fattening object interface and I don't think it is a good thing. While we may want to have sysfs representation of all devices be in /sys/devices internally we should keep the interfaces and implementation clean and do not turn it into a kitchen sink.
--
Dmitry
Quoted 10 lines · Adam Belay
Quoted 9 lines · Greg KH
Quoted 7 lines · Adam Belay
Sounds good to me. The changes to driver model internals may be substantial. For example, because buses and classes will share more code, it's reasonable to allow drivers to bind to any "device" object, even class devices. Of course this would be limited to classes that choose to implement driver matching etc. We are doing this now with the pci express port driver.
Quoted 5 lines
Quoted 2 lines
That's a bus, not a class device. Drivers bind to devices through a bus. That's why we have busses.
If class devices and devices belong in the same tree, then clearly the original distinction is artificial. "struct
bus_type" is a class of "struct device".
Huh? "struct bus_type" has a list of "struct device" and "struct drivers" that it knows about. I don't understand your use of the word "class" in this sentance. (yeah, it's a horribly overloaded term, sorry...)
Quoted 2 lines
"struct class" is a class of "struct
class_dev". We now know of devices in between these two extremes (e.g. pci express port driver).
pci express is just fine, I don't know why you don't like it :)
It's a bus, with different types of devices on it, and different types of drivers that bind to those devices. That's it.
Quoted 2 lines
It's also possible that drivers will want to bind to class devices (e.g. a partition driver binding to a block device).
Almost. Classes like input and video might want to do something like that. But that's something for the future.
Quoted 2 lines
Isn't it fair to say that the "
bus_type" vs. "class" distinction is also artificial? At the very least they are duplicating some code.
No, they are very different. busses do some work (matches drivers to devices and other bus specific glue). Classes are just a grouping of a function of a device (input, tty, misc, etc.)
Quoted 14 lines
Quoted 6 lines
Quoted 2 lines
Also, we could make driver objects a "class" and represent them in the global device tree, giving each driver instance its own unique namespace.
Huh? How would you do that? Also, we really don't have different driver "instances", so trying to represent something like that in sysfs would probably be more work than it's worth.
(all in same tree)
pci0000:00.00 <- physical device
|
\- e1000:0 <- driver
|
\- eth0 <- class device
Quoted 2 lines
We already informally have driver instances. They're pointed to in "
driver_data".
That's merely a blob of data the driver needs to use. To call that a full blown "instance" is pretty gracious. I think that trying to turn that blob into a sysfs representation would require modifying every driver in the kernel tree in a non-simple manner. That's something that I don't want to undertake at all. But if you can show me otherwise... :)
You are treating the driver in your above tree as a "bridge" between the physical device and the class device. I don't think we really need to show that in our tree, as it's an artificial thing.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
Oh, one tiny problem. "virtual devices" are not currently represented in our device tree, but are in the class tree. Things like the different vc and ttys and misc devices are examples of this. I'll just put them on the "platform" bus if no one minds.
I think we should be trying to kill off the platform bus (it's artifical and doesn't show the real relationships between these devices). Instead, just hang them off the root of the tree.
Quoted 7 lines
Quoted 2 lines
Everything that's currently a platform device go to the root? No, that's not going to happen, sorry.
Not at all. Rather, everything that's currently a platform device goes to where it actually belongs in the device tree. ACPI (and other firmware) enumerates all of these devices. They're generally children of LPCs and ISA bridges.
Not on embedded devices. Systems-on-a-chip have no "busses" generally.
Quoted 4 lines
Making a special exception for these devices is ugly when we can easily represent them like every other device. This will even be possible without ACPI for many of these devices if we create an "ISA" bus driver abstraction.
Yes, if you have a ISA and a "system" bus. But then the "platform" bus just goes back to being the system one. And you are where you started...
Quoted 3 lines
The main point here is that "platform" is really a hack to represent primitive physical devices that don't fit well into the driver model. There may be better ways of approaching this problem.
If you have a better approach, I would be glad to see it. And I don't think it's a "hack" as lots of systems only use that bus.
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
If the device doesn't have any parents or dependencies, then that's logically where it belongs.
We do have a real platform "bus" that devices hang off of. Where else is that keyboard controller at :)
As stated above, the keyboard actually does have a real location to hang off of. Nonetheless, a keyboard controller is a physical device. It's very different from a "virtual device" like a tty. Therefore, it seems unreasonable to make virtual devices belong to the "platform" bus.
Then where should virtual devices belong?
Quoted 3 lines
If a device doesn't have a parent device, it belongs at the root of the tree. That's the only obvious way to represent such a lack of dependency. This applies to both class and physical devices.
You want to put 512 tty class devices in /sys/devices/ ? I don't want to see that.
thanks,
greg k-h
Quoted 5 lines · Greg KH
But, if you think we can't break userspace by adding nested class devices just yet, I agree, and can probably just put a symlink in
/sys/class/inputto the nested devices, which will make everything "just work". I'll try that out later tonight and let you all know how it goes.
Below is a patch that does this for the event portion of input. Good news is that the symlink shows up just fine in sysfs. Bad news is that even with your previously posted patch, udev dies a horrible death.
And udev dies today with the nested stuff too, so that's not good either.
So I could just move the class devices back to the main /sys/input/ directory (instead of the nesting) which will make userspace happy, and then start working on the class -> device stuff.
Or I'll look at udev in the morning to see if it's just an easy fix...
thanks,
greg k-h
drivers/input/evdev.c +6 -1
@@ -661,6 +661,7 @@ static struct file_operations evdev_fopsstatic struct input_handle *evdev_connect (struct input_handler *handler,struct input_dev *dev,struct input_device_id *id) {struct evdev *evdev; +struct class_device *cdev;int minor;for (minor =0 ; minor <EVDEV_MINORS && evdev_table[minor]; minor++);
@@ -686,10 +687,13 @@ static struct input_handle *evdev_connec evdev_table[minor] = evdev; -class_device_create (&input_class, &dev->cdev, + cdev =class_device_create (&input_class, &dev->cdev,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + minor), dev->cdev.dev,"event%d" , minor); +/* temporary symlink to keep userspace happy */ +sysfs_create_link (&input_class.subsys.kset.kobj, &cdev->kobj, evdev->name); +return &evdev->handle; }
@@ -698,6 +702,7 @@ static void evdev_disconnect(struct inpustruct evdev *evdev = handle->private;struct evdev_list *list; +sysfs_remove_link (&input_class.subsys.kset.kobj, evdev->name);class_device_destroy (&input_class,MKDEV (INPUT_MAJOR ,EVDEV_MINOR_BASE + evdev->minor)); evdev->exist =0 ;
Quoted 7 lines · Greg KH
Quoted 5 lines · Greg KH
But, if you think we can't break userspace by adding nested class devices just yet, I agree, and can probably just put a symlink in
/sys/class/inputto the nested devices, which will make everything "just work". I'll try that out later tonight and let you all know how it goes.
Quoted 6 lines
Below is a patch that does this for the event portion of input. Good news is that the symlink shows up just fine in sysfs. Bad news is that even with your previously posted patch, udev dies a horrible death.
And udev dies today with the nested stuff too, so that's not good either.
Nevermind, that was due to the kernel oops, not udev.
Kay, your original udev patch works just fine. What I don't see is why the existing udev release doesn't also work, now that I have the symlinks set up. I'll try to figure that one out too...
thanks,
greg k-h
Quoted 12 lines · Greg KH
Quoted 11 lines · Greg KH
Quoted 5 lines · Greg KH
But, if you think we can't break userspace by adding nested class devices just yet, I agree, and can probably just put a symlink in
/sys/class/inputto the nested devices, which will make everything "just work". I'll try that out later tonight and let you all know how it goes.Below is a patch that does this for the event portion of input. Good news is that the symlink shows up just fine in sysfs. Bad news is that even with your previously posted patch, udev dies a horrible death.
Quoted 8 lines
Quoted 2 lines
And udev dies today with the nested stuff too, so that's not good either.
Nevermind, that was due to the kernel oops, not udev.
Kay, your original udev patch works just fine. What I don't see is why the existing udev release doesn't also work, now that I have the symlinks set up. I'll try to figure that one out too...
Bleah, here's a one character patch to the current udev that makes udevstart work properly with my symlink patch.
udevstart.c +1 -1
@@ -131,7 +131,7 @@ static int add_device(const char *devpatsetenv ("UDEV_RUN" , udev_run_str,1 );dbg ("add '%s'" , devpath); -snprintf (path,sizeof (path),"%s%s" , sysfs_path, devpath); +snprintf (path,sizeof (path),"%s%s/" , sysfs_path, devpath); path[sizeof (path)-1 ] ='\0' ; class_dev =sysfs_open_class_device_path (path);if (class_dev ==NULL ) {
So, any way we do it, users are going to have to upgrade udev to get things to work properly.
But I guess we should use the symlink patch in the kernel too, just to keep any other tools that don't have this kind of bug in them working properly...
Opinions?
thanks,
greg k-h
Quoted 32 lines · Kay Sievers
Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
It invents artificial subclass names below a "master" class, which is absolutely not needed.
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs! We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!
Quoted 6 lines
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree! That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.
Let me just say: I completely agree here. The hard distinction between 'real' and 'virtual' devices causes more problems than it solves.
Signature · 2 lines
Vojtech Pavlik SuSE Labs, SuSE CR
[ Uhh, sorry about the very long delay in responding to this. I was off the continent and unemployed at the time. Both of those problems are solved now. :) ]
Quoted 64 lines · Kay Sievers
Quoted 32 lines · Dmitry Torokhov
Quoted 23 lines · Kay Sievers
The nesting classes implement a fraction of a device hierarchy in
/sys/class. It moves arbitrary relation information into the class directory, where nothing else than device classification belongs. What is the rationale behind sticking device trees into class?Instead of that, I propose a unification of "
/sys/devices-devices" and "class-devices". The differentiation of both does not make sense in a wold where we can't really tell if a device is hardware or virtual.We should model _all_ devices with its actual realationship in
/sys/devicesand/sys/classshould only be a pinter to the actual devices in that place. Device like "mice", which have no parent, would sit at the top level of/sys/devices. All devices in/sys/classare only symlinks and never devices by itself.
That way userspace can read all device relation at _one_ place in a sane way, and we keep the clean class interface to have easy access to all devices of a specific group.
It gives us the right abstraction and is future proof, cause the class interface will not change when the relation between devices changes. The destinction between classes and buses would no longer be needed, and as we see in the "input" case never made sense anyway.Quoted 7 lines
/sys/class/blockwould look exactly like/sys/blocktoday. The only difference is that there are symlinks to follow instead of class devices on its own. With every device creation we will get the whole dependency path of the device in the DEVPATH and a "classsification symlink" in/sys/class. The input devices are all clearly modeled in its hierarchy, in/sys/devicesbut we also get clean class interfaces:Quoted 8 lines
Kay eased my task by enumerating all issues I have with Greg's approach. Not all the world is udev and not all class devices have "/dev" represetation so haveing one program being able to understand new sysfs hierarchy is not enough IHMO.
However I do not think that "moving" class devices into
/sys/deviceshierarchy is the right solution either because one physical device could easily end up belonging to several classes.Sure, than that physical (while that distinction is silly by itself) will just have several child devices. Look at the mouse0 and event0 in the ascii drawing.
Quoted 7 lines
I recenty got an
e-mail from Adam Belay (whom I am pulling into the discussion) regarding his desire to rearrange net/wireless representation. I think it would be quite natural to have/sys/class/net/interfacesand/sys/class/net/wireless/sys/class/net/irda, and/sys/class/net/wiredsubclasses where "interfaces" would enumerate _all_ network interfaces in the system, and the rest would show only devices of their class.That solution would keep a better device separation, sure. But it is completely incompatible with everything we ever had in sysfs and nobody wants to rewrite _all_ userspace programs.
It invents artificial subclass names below a "master" class, which is absolutely not needed.
It creates the magic "interfaces" directory, which is confusing, cause it classifies devices by itself.
Quoted 8 lines
It doesn't represent any relationship and hierarchy of devices and adding a forest of magic symlinks and "device" pointers is a very bad design. The proposed "inter-class" symlinks make it even harder to understand sysfs as it already is.
The biggest problem with current sysfs is that the driver hacker has to decide if the device is "hardware" or "virtual" which in a lot of cases just can't tell and this distiction doesn't make any sense today.
Could you provide an example of this? The driver model is currently designed to handle two basic types of objects:
- Physical objects (mapping to struct device) that are discovered by a bus driver's probing/scanning routines.
- Logical objects (mapping to struct class_device) that are created when a driver binds to a device and registers with the device class that the driver belongs to.
Most of that should happen behind the scenes in the bus and class code respectively.
Quoted 3 lines
All the more complex subsystems use "virtual buses" and an unconnected bunch of class-devices to model its sysfs represention, which is just to work around a major design flaw in sysfs!
I wouldn't call this a design flaw. This was just willingness in the implementors of those subsystems to overload the current design features, and unwillingness to add new infrastructure that better represented what they wanted to do. Don't blame the driver model for this; it was more a lack of time and/or understanding of what needed to be done.
Note this is exactly why /sys/block exists, and even why kobjects were created - someone wanted to export things that weren't currently represented, so they overloaded the existing structures, and did so in a fairly nasty way.
Quoted 11 lines
We really should get _one_ device tree with its natural hierarchy, get rid of the stupid "device"-link, the PHYSDEVPATH and the unconnected class devices. Every device should just carry its dependency tree in it _own_ devpath!
I'm very sure, we want a unified tree in
/sys/devices, regardless of the type of device, to represent the global hierarchy wich is exactly what you want to know from a device tree!
That way we stack "virtual" _and_ "physical" in a sane manner and at the same time get very clean class interfaces. We would stop to mix up "hierarchy" and "classes" all over the tree.
For what purpose? To make udev easier to program? Or, to make it easier to determine what attributes are located where? Or, to determine what devices map to what class devices? (Really, I'm curious).
Recall tht sysfs is designed to export kernel objects in a natural manner. What we have now is mostly natural. There are some artificial bits to it (the most agregious are things like usb-serial), but the distinction between physical devices and class devices and their relationships with drivers and the buses that they're on is clearly spelled out.
So what if there is a forest of symlinks?
If you want a unified representation of every thing (objects and attrributes) that represent a single piece of hardware (i.e. in a compact, single screen full of text), then that should be done in userspace, IMHO. :)
Thanks,
Pat
NACK. The whole point of classes is to have common attributes and behaviours over a set of devices. There's much more than the dev attribute to them. Please just fix the input code to get their semantics right instead.
Dmitry Torokhov
maintainerQuoted 5 lines · Christoph Hellwig
NACK. The whole point of classes is to have common attributes and behaviours over a set of devices. There's much more than the dev attribute to them. Please just fix the input code to get their semantics right instead.
What kind of changes would you like to see in the input system? Currently it maps perfectly well on to what we have in sysfs (using pair of input and input_dev classes), it is just that we do not really like the general sysfs structure and would like to improve it.
--
Dmitry