2005-10-13 02:11:58

by Greg KH

[permalink] [raw]
Subject: [patch 0/8] 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


2005-10-13 02:12:58

by Greg KH

[permalink] [raw]
Subject: [patch 2/8] Driver Core: fix up all callers of class_device_create()

From: 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.

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
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(-)

--- gregkh-2.6.orig/drivers/usb/core/devio.c
+++ gregkh-2.6/drivers/usb/core/devio.c
@@ -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);

--- gregkh-2.6.orig/drivers/usb/core/file.c
+++ gregkh-2.6/drivers/usb/core/file.c
@@ -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;
--- gregkh-2.6.orig/drivers/usb/core/hcd.c
+++ gregkh-2.6/drivers/usb/core/hcd.c
@@ -782,7 +782,8 @@ static int usb_register_bus(struct usb_b
return -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);
--- gregkh-2.6.orig/drivers/video/fbmem.c
+++ gregkh-2.6/drivers/video/fbmem.c
@@ -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 */
--- gregkh-2.6.orig/drivers/block/aoe/aoechr.c
+++ gregkh-2.6/drivers/block/aoe/aoechr.c
@@ -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);

--- gregkh-2.6.orig/drivers/block/paride/pg.c
+++ gregkh-2.6/drivers/block/paride/pg.c
@@ -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",
--- gregkh-2.6.orig/drivers/block/paride/pt.c
+++ gregkh-2.6/drivers/block/paride/pt.c
@@ -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,
--- gregkh-2.6.orig/drivers/char/dsp56k.c
+++ gregkh-2.6/drivers/char/dsp56k.c
@@ -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");
--- gregkh-2.6.orig/drivers/char/ip2main.c
+++ gregkh-2.6/drivers/char/ip2main.c
@@ -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);
--- gregkh-2.6.orig/drivers/char/istallion.c
+++ gregkh-2.6/drivers/char/istallion.c
@@ -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);
}

--- gregkh-2.6.orig/drivers/char/lp.c
+++ gregkh-2.6/drivers/char/lp.c
@@ -805,7 +805,7 @@ static int lp_register(int nr, struct pa
if (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);
--- gregkh-2.6.orig/drivers/char/mem.c
+++ gregkh-2.6/drivers/char/mem.c
@@ -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);
--- gregkh-2.6.orig/drivers/char/misc.c
+++ gregkh-2.6/drivers/char/misc.c
@@ -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);
--- gregkh-2.6.orig/drivers/char/ppdev.c
+++ gregkh-2.6/drivers/char/ppdev.c
@@ -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);
}

--- gregkh-2.6.orig/drivers/char/raw.c
+++ gregkh-2.6/drivers/char/raw.c
@@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct fi
static 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,
--- gregkh-2.6.orig/drivers/char/snsc.c
+++ gregkh-2.6/drivers/char/snsc.c
@@ -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,
--- gregkh-2.6.orig/drivers/char/stallion.c
+++ gregkh-2.6/drivers/char/stallion.c
@@ -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;
--- gregkh-2.6.orig/drivers/char/tipar.c
+++ gregkh-2.6/drivers/char/tipar.c
@@ -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),
--- gregkh-2.6.orig/drivers/char/tty_io.c
+++ gregkh-2.6/drivers/char/tty_io.c
@@ -2728,7 +2728,7 @@ void tty_register_device(struct tty_driv
pty_line_name(driver, index, name);
else
tty_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
--- gregkh-2.6.orig/drivers/char/ftape/zftape/zftape-init.c
+++ gregkh-2.6/drivers/char/ftape/zftape/zftape-init.c
@@ -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);
--- gregkh-2.6.orig/drivers/char/ipmi/ipmi_devintf.c
+++ gregkh-2.6/drivers/char/ipmi/ipmi_devintf.c
@@ -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)
--- gregkh-2.6.orig/drivers/char/vc_screen.c
+++ gregkh-2.6/drivers/char/vc_screen.c
@@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *t
devfs_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;
}
--- gregkh-2.6.orig/drivers/char/viotape.c
+++ gregkh-2.6/drivers/char/viotape.c
@@ -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);
--- gregkh-2.6.orig/drivers/hwmon/hwmon.c
+++ gregkh-2.6/drivers/hwmon/hwmon.c
@@ -45,7 +45,7 @@ struct class_device *hwmon_device_regist
return 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))
--- gregkh-2.6.orig/drivers/ide/ide-tape.c
+++ gregkh-2.6/drivers/ide/ide-tape.c
@@ -4884,9 +4884,9 @@ static int ide_tape_probe(struct device

idetape_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),
--- gregkh-2.6.orig/drivers/ieee1394/dv1394.c
+++ gregkh-2.6/drivers/ieee1394/dv1394.c
@@ -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);
--- gregkh-2.6.orig/drivers/ieee1394/raw1394.c
+++ gregkh-2.6/drivers/ieee1394/raw1394.c
@@ -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;
--- gregkh-2.6.orig/drivers/ieee1394/video1394.c
+++ gregkh-2.6/drivers/ieee1394/video1394.c
@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct h
hpsb_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),
--- gregkh-2.6.orig/drivers/infiniband/core/ucm.c
+++ gregkh-2.6/drivers/infiniband/core/ucm.c
@@ -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);
--- gregkh-2.6.orig/drivers/isdn/capi/capi.c
+++ gregkh-2.6/drivers/isdn/capi/capi.c
@@ -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");

--- gregkh-2.6.orig/drivers/macintosh/adb.c
+++ gregkh-2.6/drivers/macintosh/adb.c
@@ -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");
}
--- gregkh-2.6.orig/drivers/media/dvb/dvb-core/dvbdev.c
+++ gregkh-2.6/drivers/media/dvb/dvb-core/dvbdev.c
@@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adapt
S_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",
--- gregkh-2.6.orig/drivers/message/i2o/iop.c
+++ gregkh-2.6/drivers/message/i2o/iop.c
@@ -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);
--- gregkh-2.6.orig/drivers/mtd/mtdchar.c
+++ gregkh-2.6/drivers/mtd/mtdchar.c
@@ -24,10 +24,10 @@ static void mtd_notify_add(struct mtd_in
if (!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);
}
--- gregkh-2.6.orig/drivers/net/ppp_generic.c
+++ gregkh-2.6/drivers/net/ppp_generic.c
@@ -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)
--- gregkh-2.6.orig/drivers/net/wan/cosa.c
+++ gregkh-2.6/drivers/net/wan/cosa.c
@@ -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,
--- gregkh-2.6.orig/drivers/s390/char/tape_class.c
+++ gregkh-2.6/drivers/s390/char/tape_class.c
@@ -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
--- gregkh-2.6.orig/drivers/s390/char/vmlogrdr.c
+++ gregkh-2.6/drivers/s390/char/vmlogrdr.c
@@ -787,6 +787,7 @@ vmlogrdr_register_device(struct vmlogrdr
return ret;
}
priv->class_device = class_device_create(
+ NULL,
vmlogrdr_class,
MKDEV(vmlogrdr_major, priv->minor_num),
dev,
--- gregkh-2.6.orig/drivers/scsi/ch.c
+++ gregkh-2.6/drivers/scsi/ch.c
@@ -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);

--- gregkh-2.6.orig/drivers/scsi/osst.c
+++ gregkh-2.6/drivers/scsi/osst.c
@@ -5627,7 +5627,7 @@ static void osst_sysfs_add(dev_t dev, st

if (!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;
--- gregkh-2.6.orig/drivers/scsi/sg.c
+++ gregkh-2.6/drivers/scsi/sg.c
@@ -1550,7 +1550,7 @@ sg_add(struct class_device *cl_dev, stru
if (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);
--- gregkh-2.6.orig/drivers/scsi/st.c
+++ gregkh-2.6/drivers/scsi/st.c
@@ -4375,7 +4375,7 @@ static void do_create_class_files(struct
snprintf(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);
--- gregkh-2.6.orig/drivers/input/evdev.c
+++ gregkh-2.6/drivers/input/evdev.c
@@ -689,7 +689,7 @@ static struct input_handle *evdev_connec

devfs_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);

--- gregkh-2.6.orig/drivers/input/joydev.c
+++ gregkh-2.6/drivers/input/joydev.c
@@ -516,7 +516,7 @@ static struct input_handle *joydev_conne

devfs_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);

--- gregkh-2.6.orig/drivers/input/mousedev.c
+++ gregkh-2.6/drivers/input/mousedev.c
@@ -651,7 +651,7 @@ static struct input_handle *mousedev_con

devfs_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
--- gregkh-2.6.orig/drivers/input/tsdev.c
+++ gregkh-2.6/drivers/input/tsdev.c
@@ -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);

--- gregkh-2.6.orig/arch/i386/kernel/cpuid.c
+++ gregkh-2.6/arch/i386/kernel/cpuid.c
@@ -163,7 +163,7 @@ static int cpuid_class_device_create(int
int 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;
--- gregkh-2.6.orig/arch/i386/kernel/msr.c
+++ gregkh-2.6/arch/i386/kernel/msr.c
@@ -246,7 +246,7 @@ static int msr_class_device_create(int i
int 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;
--- gregkh-2.6.orig/sound/core/sound.c
+++ gregkh-2.6/sound/core/sound.c
@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_ca
devfs_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;
--- gregkh-2.6.orig/sound/oss/soundcard.c
+++ gregkh-2.6/sound/oss/soundcard.c
@@ -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);
}
--- gregkh-2.6.orig/sound/sound_core.c
+++ gregkh-2.6/sound/sound_core.c
@@ -174,7 +174,7 @@ static int sound_insert_unit(struct soun

devfs_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;

--- gregkh-2.6.orig/fs/coda/psdev.c
+++ gregkh-2.6/fs/coda/psdev.c
@@ -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)

--

2005-10-13 02:12:29

by Greg KH

[permalink] [raw]
Subject: [patch 7/8] input: remove the input_class structure, as it is unused.

From: Greg Kroah-Hartman <[email protected]>

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/input/input.c | 18 +++---------------
include/linux/input.h | 1 -
2 files changed, 3 insertions(+), 16 deletions(-)

--- gregkh-2.6.orig/drivers/input/input.c
+++ gregkh-2.6/drivers/input/input.c
@@ -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);
}

--- gregkh-2.6.orig/include/linux/input.h
+++ gregkh-2.6/include/linux/input.h
@@ -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

--

2005-10-13 02:12:25

by Greg KH

[permalink] [raw]
Subject: [patch 6/8] input: move the input class devices under their new input_dev devices

From: Greg Kroah-Hartman <[email protected]>

Signed-off-by: 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(-)

--- gregkh-2.6.orig/drivers/input/mousedev.c
+++ gregkh-2.6/drivers/input/mousedev.c
@@ -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 i
struct 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);
}
--- gregkh-2.6.orig/drivers/input/evdev.c
+++ gregkh-2.6/drivers/input/evdev.c
@@ -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 inpu
struct 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;

--- gregkh-2.6.orig/drivers/input/joydev.c
+++ gregkh-2.6/drivers/input/joydev.c
@@ -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 inp
struct 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) {
--- gregkh-2.6.orig/drivers/input/tsdev.c
+++ gregkh-2.6/drivers/input/tsdev.c
@@ -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 inpu
struct 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;


--

2005-10-13 02:11:58

by Greg KH

[permalink] [raw]
Subject: [patch 4/8] input: register the input class device sooner

From: Greg Kroah-Hartman <[email protected]>

This is needed so we can actually use the class device within the input
handlers.

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/input/input.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

--- gregkh-2.6.orig/drivers/input/input.c
+++ gregkh-2.6/drivers/input/input.c
@@ -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

--

2005-10-13 02:13:41

by Greg KH

[permalink] [raw]
Subject: [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...

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/base/class.c | 125 +++++++++++++++++++++++++++++++------------------
include/linux/device.h | 13 +++--
2 files changed, 91 insertions(+), 47 deletions(-)

--- gregkh-2.6.orig/drivers/base/class.c
+++ gregkh-2.6/drivers/base/class.c
@@ -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 * cls

static 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 kob
kfree(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 clas

int 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_device
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);

/* notify any interfaces this device is now here */
- if (parent) {
- down(&parent->sem);
- list_add_tail(&class_dev->node, &parent->children);
- list_for_each_entry(class_intf, &parent->interfaces, node)
+ if (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_devic
kobject_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(s

void class_device_put(struct class_device *class_dev)
{
- kobject_put(&class_dev->kobj);
+ if (class_dev)
+ kobject_put(&class_dev->kobj);
}


--- gregkh-2.6.orig/include/linux/device.h
+++ gregkh-2.6/include/linux/device.h
@@ -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(s

extern 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);



--

2005-10-13 02:12:54

by Greg KH

[permalink] [raw]
Subject: [patch 5/8] input: export input_dev_class so that input drivers can use it.

From: Greg Kroah-Hartman <[email protected]>

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/input/input.c | 3 ++-
include/linux/input.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)

--- gregkh-2.6.orig/drivers/input/input.c
+++ gregkh-2.6/drivers/input/input.c
@@ -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 cla
module_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,
--- gregkh-2.6.orig/include/linux/input.h
+++ gregkh-2.6/include/linux/input.h
@@ -1075,6 +1075,7 @@ static inline void input_set_abs_params(
}

extern struct class *input_class;
+extern struct class input_dev_class;

#endif
#endif

--

2005-10-13 02:12:57

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Wed, Oct 12, 2005 at 07:08:44PM -0700, Greg KH wrote:
> 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.

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

2005-10-13 02:12:59

by Greg KH

[permalink] [raw]
Subject: [patch 8/8] input: rename input_dev_class to input_class to be correct.

From: Greg Kroah-Hartman <[email protected]>


Signed-off-by: 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(-)

--- gregkh-2.6.orig/drivers/input/evdev.c
+++ gregkh-2.6/drivers/input/evdev.c
@@ -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 inpu
struct 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;

--- gregkh-2.6.orig/drivers/input/input.c
+++ gregkh-2.6/drivers/input/input.c
@@ -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 cla
module_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);
--- gregkh-2.6.orig/drivers/input/joydev.c
+++ gregkh-2.6/drivers/input/joydev.c
@@ -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 inp
struct 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) {
--- gregkh-2.6.orig/drivers/input/mousedev.c
+++ gregkh-2.6/drivers/input/mousedev.c
@@ -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 i
struct 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);
}
--- gregkh-2.6.orig/drivers/input/tsdev.c
+++ gregkh-2.6/drivers/input/tsdev.c
@@ -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 inpu
struct 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;

--- gregkh-2.6.orig/include/linux/input.h
+++ gregkh-2.6/include/linux/input.h
@@ -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

--

2005-10-13 02:12:57

by Greg KH

[permalink] [raw]
Subject: [patch 3/8] Driver Core: document struct class_device properly

From: Greg Kroah-Hartman <[email protected]>

Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/device.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)

--- gregkh-2.6.orig/include/linux/device.h
+++ gregkh-2.6/include/linux/device.h
@@ -203,6 +203,30 @@ struct class_device_attribute class_devi
extern 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;


--

2005-10-13 06:38:42

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Wed, Oct 12, 2005 at 07:08:44PM -0700, Greg KH wrote:

> 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

> 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. ]

> 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.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-10-13 10:58:29

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Wed, Oct 12, 2005 at 07:08:44PM -0700, Greg KH wrote:
> 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.

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.

> 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?

Me at least! :) As we can't distinguish between the type of class device
which is nested. And that information is lost.

> 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.

> 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?

Sure, we really need to know this! We could only hardcode names and match
against this to get meaningful information out of that.

> 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.

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.

> 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.

> 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

2005-10-13 21:21:59

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On 10/13/05, Vojtech Pavlik <[email protected]> wrote:
> On Wed, Oct 12, 2005 at 07:08:44PM -0700, Greg KH wrote:
> >
> > 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.

> > 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

2005-10-13 21:35:28

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On 10/13/05, Kay Sievers <[email protected]> wrote:
>
> 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:
>

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

2005-10-13 23:38:18

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Wed, Oct 12, 2005 at 07:10:01PM -0700, Greg KH wrote:
> On Wed, Oct 12, 2005 at 07:08:44PM -0700, Greg KH wrote:
> > 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.
>
> 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

---
diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c
index edf751b..e95c919 100644
--- a/libsysfs/sysfs_class.c
+++ b/libsysfs/sysfs_class.c
@@ -227,16 +227,46 @@ struct sysfs_class_device *sysfs_get_cla
if (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;
}
diff --git a/udevstart.c b/udevstart.c
index ce96f38..09f0e5d 100644
--- a/udevstart.c
+++ b/udevstart.c
@@ -79,7 +79,7 @@ static int device_list_insert(const char
struct 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);
}

2005-10-13 23:37:39

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

Am Do 13.10.2005 23:35 schrieb Dmitry Torokhov
<[email protected]>:

> On 10/13/05, Kay Sievers <[email protected]> wrote:
> >
[ ... ]
> >
> > 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.
> >
[ ... ]
> >
>
> 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.

> 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.
>
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

2005-10-14 08:45:58

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
> On 10/13/05, Kay Sievers <[email protected]> wrote:
> >
> > 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:
> >
>
> 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.

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.

> 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.

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

2005-10-14 09:53:33

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

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.

2005-10-14 12:14:27

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Fri, Oct 14, 2005 at 10:45:54AM +0200, Kay Sievers wrote:
> On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
> > On 10/13/05, Kay Sievers <[email protected]> wrote:
> > >
> > > 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:
> > >
> >
> > 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.
>
> 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.
>
> > 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.
>
> 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.

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

2005-10-14 12:50:20

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work


On Fri, 14 Oct 2005, Kay Sievers wrote:

> On Fri, Oct 14, 2005 at 10:45:54AM +0200, Kay Sievers wrote:
>> On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
>>> On 10/13/05, Kay Sievers <[email protected]> wrote:
>>>>
>>>> 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:
>>>>
>>>
>>> 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.
>>
>> 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.
>>
>>> 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.
>>
>> 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.
>
> 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

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.

2005-10-14 13:49:26

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Fri, Oct 14, 2005 at 08:49:52AM -0400, linux-os (Dick Johnson) wrote:
>
> On Fri, 14 Oct 2005, Kay Sievers wrote:
>
> > On Fri, Oct 14, 2005 at 10:45:54AM +0200, Kay Sievers wrote:
> >> On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
> >>> On 10/13/05, Kay Sievers <[email protected]> wrote:
> >>>>
> >>>> 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:
> >>>>
> >>>
> >>> 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.
> >>
> >> 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.
> >>
> >>> 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.
> >>
> >> 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.
> >
> > 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
>
> 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.

Welcome to Linux!
Sysfs was never and will not be involved with mounting or device nodes!

Kay

2005-10-14 16:36:41

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On 10/14/05, Christoph Hellwig <[email protected]> wrote:
> 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

2005-10-14 17:02:33

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On 10/14/05, Kay Sievers <[email protected]> wrote:
> On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
> > On 10/13/05, Kay Sievers <[email protected]> wrote:
> > >
> > > 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:
> > >
> >
> > 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.
>
> 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.
>
> > 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.
>
> 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?

> 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".

> 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.

> 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.

> 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?

> 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.
>

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

2005-10-15 15:08:58

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Fri, Oct 14, 2005 at 12:02:30PM -0500, Dmitry Torokhov wrote:
> On 10/14/05, Kay Sievers <[email protected]> wrote:
> > On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
> > > On 10/13/05, Kay Sievers <[email protected]> wrote:
> > > >
> > > > 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:
> > > >
> > >
> > > 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.
> >
> > 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.
> >
> > > 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.
> >
> > 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.

> We are moving /sys/block
> to /sys/class so 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.

> 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.

> Btw, is your proposal with moving it all into /sys/device less 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!

> > 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.

> > 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.

> > 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.

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.

> 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!

> > 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...

> > 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.
> >
>
> 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.

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.)

> 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.

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

2005-10-17 05:41:34

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Saturday 15 October 2005 10:08, Kay Sievers wrote:
> On Fri, Oct 14, 2005 at 12:02:30PM -0500, Dmitry Torokhov wrote:
> >
> > 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.
>
> > We are moving /sys/block
> > to /sys/class so 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.
>

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...

> > 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..

> > Btw, is your proposal with moving it all into /sys/device less 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..

> > > 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.
>

Call it "subsystem" actually.

> > > 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!
>

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.

> 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.
>

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.

--
Dmitry

2005-10-17 09:26:24

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Fri, Oct 14, 2005 at 10:45:54AM +0200, Kay Sievers wrote:

> 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!
>
> 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.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-10-17 10:02:26

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Fri, Oct 14, 2005 at 02:14:23PM +0200, Kay Sievers wrote:

> 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:

> /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.

> /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
> | | | `-- 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.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-10-17 21:45:15

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Sat, Oct 15, 2005 at 05:08:55PM +0200, Kay Sievers wrote:
> 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.

I agree.

> > Btw, is your proposal with moving it all into /sys/device less 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...

2005-10-17 21:54:53

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On 10/17/05, Greg KH <[email protected]> wrote:
> 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 :)
>

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

2005-10-17 23:21:53

by Adam Belay

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 02:44:30PM -0700, Greg KH wrote:
> On Sat, Oct 15, 2005 at 05:08:55PM +0200, Kay Sievers wrote:
> > 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.
>
> I agree.
>
> > > Btw, is your proposal with moving it all into /sys/device less 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?

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.

>
> 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

2005-10-17 23:24:16

by Adam Belay

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 04:54:52PM -0500, Dmitry Torokhov wrote:
> On 10/17/05, Greg KH <[email protected]> wrote:
> > 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 :)
> >
>
> 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

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

2005-10-17 23:44:04

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 07:24:30PM -0400, Adam Belay wrote:
> On Mon, Oct 17, 2005 at 02:44:30PM -0700, Greg KH wrote:
> > On Sat, Oct 15, 2005 at 05:08:55PM +0200, Kay Sievers wrote:
> > > 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.
> >
> > I agree.
> >
> > > > Btw, is your proposal with moving it all into /sys/device less 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...)

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.

> > 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.

> 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...

> 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.
>
> >
> > 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.

We do the same in HAL every unconnected object just lives in the root of
the device tree.

Thanks,
Kay

2005-10-18 00:03:42

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 07:26:55PM -0400, Adam Belay wrote:
> On Mon, Oct 17, 2005 at 04:54:52PM -0500, Dmitry Torokhov wrote:
> > On 10/17/05, Greg KH <[email protected]> wrote:
> > > 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 :)
> > >
> >
> > 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.

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.

> 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

2005-10-18 05:13:26

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Monday 17 October 2005 05:02, Vojtech Pavlik wrote:
> On Fri, Oct 14, 2005 at 02:14:23PM +0200, Kay Sievers wrote:
>
> > 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:
>
> > /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.
>

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.

--
Dmitry

2005-10-18 05:46:26

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 07:24:30PM -0400, Adam Belay wrote:
>
> 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.

> 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.

Hm, I don't really know...

> 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.

> > 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.

> 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

2005-10-18 06:05:27

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 02:44:30PM -0700, Greg KH wrote:
> 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.

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


--- gregkh-2.6.orig/drivers/input/evdev.c 2005-10-16 13:09:07.000000000 -0700
+++ gregkh-2.6/drivers/input/evdev.c 2005-10-17 22:47:40.000000000 -0700
@@ -661,6 +661,7 @@ static struct file_operations evdev_fops
static 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 inpu
struct 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;

2005-10-18 07:05:51

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 11:04:35PM -0700, Greg KH wrote:
> On Mon, Oct 17, 2005 at 02:44:30PM -0700, Greg KH wrote:
> > 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.
>
> 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

2005-10-18 07:15:39

by Adam Belay

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Mon, Oct 17, 2005 at 10:26:17PM -0700, Greg KH wrote:
> On Mon, Oct 17, 2005 at 07:24:30PM -0400, Adam Belay wrote:
> >
> > 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.

>
> > 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".

>
> > > 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.

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.

>
> > 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

2005-10-18 07:35:39

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Tue, Oct 18, 2005 at 12:05:15AM -0700, Greg KH wrote:
> On Mon, Oct 17, 2005 at 11:04:35PM -0700, Greg KH wrote:
> > On Mon, Oct 17, 2005 at 02:44:30PM -0700, Greg KH wrote:
> > > 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.
> >
> > 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...

Bleah, here's a one character patch to the current udev that makes
udevstart work properly with my symlink patch.

diff --git a/udevstart.c b/udevstart.c
index ce96f38..ce72b82 100644
--- a/udevstart.c
+++ b/udevstart.c
@@ -131,7 +131,7 @@ static int add_device(const char *devpat
setenv("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

2005-10-18 08:34:36

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Tue, Oct 18, 2005 at 03:18:22AM -0400, Adam Belay wrote:

> 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.

--
Vojtech Pavlik
SuSE Labs, SuSE CR

2005-10-18 15:08:37

by Kay Sievers

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Tue, Oct 18, 2005 at 03:18:22AM -0400, Adam Belay wrote:
> On Mon, Oct 17, 2005 at 10:26:17PM -0700, Greg KH wrote:
> > On Mon, Oct 17, 2005 at 07:24:30PM -0400, Adam Belay wrote:
> > >
> > > 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.

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.

> > > > 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

2005-10-18 15:41:59

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On 10/18/05, Kay Sievers <[email protected]> wrote:
> On Tue, Oct 18, 2005 at 03:18:22AM -0400, Adam Belay wrote:
> > On Mon, Oct 17, 2005 at 10:26:17PM -0700, Greg KH wrote:
> > > On Mon, Oct 17, 2005 at 07:24:30PM -0400, Adam Belay wrote:
> > > >
> > > > 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.
>
> 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.
>
> > > > > 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
>

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

2005-10-18 16:53:32

by Greg KH

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work

On Tue, Oct 18, 2005 at 03:18:22AM -0400, Adam Belay wrote:
> On Mon, Oct 17, 2005 at 10:26:17PM -0700, Greg KH wrote:
> > On Mon, Oct 17, 2005 at 07:24:30PM -0400, Adam Belay wrote:
> > >
> > > 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".

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...)

> "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.

> 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.

> 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.)

> > > 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".

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.

> > > > 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.
>
> 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.

> 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...

> 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.

> > > 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?

> 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

2005-12-01 19:00:06

by Patrick Mochel

[permalink] [raw]
Subject: Re: [patch 0/8] Nesting class_device patches that actually work


[ 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. :) ]


On Fri, 14 Oct 2005, Kay Sievers wrote:

> On Thu, Oct 13, 2005 at 04:35:25PM -0500, Dmitry Torokhov wrote:
> > On 10/13/05, Kay Sievers <[email protected]> wrote:
> > >
> > > 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:
> > >
> >
> > 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.
>
> 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.
>
> > 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.
>
> 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.

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.

> 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.

> 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