Parent repository is bk://kernel.bkbits.net/gregkh/linux/driver-2.6 James.Bottomley@SteelEye.com|ChangeSet|20040314215032|19484 James.Bottomley diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile --- a/drivers/base/Makefile Sun Mar 14 14:06:40 2004 +++ b/drivers/base/Makefile Sun Mar 14 14:06:40 2004 @@ -6,3 +6,8 @@ obj-y += power/ obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o + +ifeq ($(CONFIG_DEBUG_DRIVER),y) +EXTRA_CFLAGS += -DDEBUG +endif + diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c --- a/drivers/base/bus.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/bus.c Sun Mar 14 14:06:40 2004 @@ -9,10 +9,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include #include diff -Nru a/drivers/base/class.c b/drivers/base/class.c --- a/drivers/base/class.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/class.c Sun Mar 14 14:06:40 2004 @@ -11,10 +11,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include #include @@ -106,13 +102,21 @@ int class_register(struct class * cls) { + int error; + pr_debug("device class '%s': registering\n",cls->name); INIT_LIST_HEAD(&cls->children); INIT_LIST_HEAD(&cls->interfaces); - kobject_set_name(&cls->subsys.kset.kobj,cls->name); + error = kobject_set_name(&cls->subsys.kset.kobj,cls->name); + if (error) + return error; + subsys_set_kset(cls,class_subsys); - subsystem_register(&cls->subsys); + + error = subsystem_register(&cls->subsys); + if (error) + return error; return 0; } diff -Nru a/drivers/base/class_simple.c b/drivers/base/class_simple.c --- a/drivers/base/class_simple.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/class_simple.c Sun Mar 14 14:06:40 2004 @@ -9,10 +9,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include #include diff -Nru a/drivers/base/core.c b/drivers/base/core.c --- a/drivers/base/core.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/core.c Sun Mar 14 14:06:40 2004 @@ -9,10 +9,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include #include diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c --- a/drivers/base/driver.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/driver.c Sun Mar 14 14:06:40 2004 @@ -9,10 +9,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include #include diff -Nru a/drivers/base/power/Makefile b/drivers/base/power/Makefile --- a/drivers/base/power/Makefile Sun Mar 14 14:06:40 2004 +++ b/drivers/base/power/Makefile Sun Mar 14 14:06:40 2004 @@ -1,2 +1,6 @@ obj-y := shutdown.o obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o + +ifeq ($(CONFIG_DEBUG_DRIVER),y) +EXTRA_CFLAGS += -DDEBUG +endif diff -Nru a/drivers/base/power/main.c b/drivers/base/power/main.c --- a/drivers/base/power/main.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/power/main.c Sun Mar 14 14:06:40 2004 @@ -20,10 +20,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include "power.h" diff -Nru a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c --- a/drivers/base/power/shutdown.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/power/shutdown.c Sun Mar 14 14:06:40 2004 @@ -9,10 +9,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c --- a/drivers/base/sys.c Sun Mar 14 14:06:40 2004 +++ b/drivers/base/sys.c Sun Mar 14 14:06:40 2004 @@ -13,10 +13,6 @@ */ #include -#ifdef CONFIG_DEBUG_DRIVER -#define DEBUG 1 -#endif - #include #include #include diff -Nru a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h --- a/drivers/char/drm/drm_stub.h Sun Mar 14 14:06:40 2004 +++ b/drivers/char/drm/drm_stub.h Sun Mar 14 14:06:40 2004 @@ -35,6 +35,8 @@ #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ +static struct class_simple *drm_class; + /** Stub list. One for each minor. */ static struct drm_stub_list { const char *name; @@ -117,6 +119,7 @@ DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root), &DRM(stub_list)[i] .dev_root); + class_simple_device_add(drm_class, MKDEV(DRM_MAJOR, i), NULL, name); return i; } } @@ -141,6 +144,7 @@ DRM(proc_cleanup)(minor, DRM(stub_root), DRM(stub_list)[minor].dev_root); if (minor) { + class_simple_device_remove(MKDEV(DRM_MAJOR, minor)); inter_module_put("drm"); } else { inter_module_unregister("drm"); @@ -148,6 +152,8 @@ sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS, DRM_MEM_STUB); unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_device_remove(MKDEV(DRM_MAJOR, minor)); + class_simple_destroy(drm_class); } return 0; } @@ -170,10 +176,23 @@ drm_device_t *dev) { struct drm_stub_info *i = NULL; + int ret1; + int ret2; DRM_DEBUG("\n"); - if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) + ret1 = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops)); + if (!ret1) { + drm_class = class_simple_create(THIS_MODULE, "drm"); + if (IS_ERR(drm_class)) { + printk (KERN_ERR "Error creating drm class.\n"); + unregister_chrdev(DRM_MAJOR, "drm"); + return PTR_ERR(drm_class); + } + } + else if (ret1 == -EBUSY) i = (struct drm_stub_info *)inter_module_get("drm"); + else + return -1; if (i) { /* Already registered */ @@ -186,8 +205,18 @@ DRM_DEBUG("calling inter_module_register\n"); inter_module_register("drm", THIS_MODULE, &DRM(stub_info)); } - if (DRM(stub_info).info_register) - return DRM(stub_info).info_register(name, fops, dev); + if (DRM(stub_info).info_register) { + ret2 = DRM(stub_info).info_register(name, fops, dev); + if (ret2) { + if (!ret1) { + unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_destroy(drm_class); + } + if (!i) + inter_module_unregister("drm"); + } + return ret2; + } return -1; } diff -Nru a/drivers/char/lp.c b/drivers/char/lp.c --- a/drivers/char/lp.c Sun Mar 14 14:06:40 2004 +++ b/drivers/char/lp.c Sun Mar 14 14:06:40 2004 @@ -869,7 +869,7 @@ int __init lp_init (void) { - int i; + int i, err = 0; if (parport_nr[0] == LP_PARPORT_OFF) return 0; @@ -900,10 +900,15 @@ devfs_mk_dir("printers"); lp_class = class_simple_create(THIS_MODULE, "printer"); + if (IS_ERR(lp_class)) { + err = PTR_ERR(lp_class); + goto out_devfs; + } if (parport_register_driver (&lp_driver)) { printk (KERN_ERR "lp: unable to register with parport\n"); - return -EIO; + err = -EIO; + goto out_class; } if (!lp_count) { @@ -915,6 +920,13 @@ } return 0; + +out_class: + class_simple_destroy(lp_class); +out_devfs: + devfs_remove("printers"); + unregister_chrdev(LP_MAJOR, "lp"); + return err; } static int __init lp_init_module (void) diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c --- a/drivers/char/misc.c Sun Mar 14 14:06:40 2004 +++ b/drivers/char/misc.c Sun Mar 14 14:06:40 2004 @@ -342,6 +342,7 @@ if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { printk("unable to get major %d for misc devices\n", MISC_MAJOR); + class_simple_destroy(misc_class); return -EIO; } return 0; diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c Sun Mar 14 14:06:40 2004 +++ b/drivers/char/tty_io.c Sun Mar 14 14:06:40 2004 @@ -2195,8 +2195,6 @@ EXPORT_SYMBOL(tty_register_device); EXPORT_SYMBOL(tty_unregister_device); -static struct kobject tty_kobj = {.name = "tty"}; - struct tty_driver *alloc_tty_driver(int lines) { struct tty_driver *driver; @@ -2296,15 +2294,11 @@ driver->termios_locked = NULL; } - driver->cdev.kobj.parent = &tty_kobj; - strcpy(driver->cdev.kobj.name, driver->name); - for (s = strchr(driver->cdev.kobj.name, '/'); s; s = strchr(s, '/')) - *s = '!'; cdev_init(&driver->cdev, &tty_fops); driver->cdev.owner = driver->owner; error = cdev_add(&driver->cdev, dev, driver->num); if (error) { - kobject_del(&driver->cdev.kobj); + cdev_del(&driver->cdev); unregister_chrdev_region(dev, driver->num); driver->ttys = NULL; driver->termios = driver->termios_locked = NULL; @@ -2420,7 +2414,9 @@ } postcore_initcall(tty_class_init); - + +/* 3/2004 jmc: why do these devices exist? */ + static struct cdev tty_cdev, console_cdev; #ifdef CONFIG_UNIX98_PTYS static struct cdev ptmx_cdev; @@ -2435,7 +2431,6 @@ */ static int __init tty_init(void) { - strcpy(tty_cdev.kobj.name, "dev.tty"); cdev_init(&tty_cdev, &tty_fops); if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) @@ -2443,7 +2438,6 @@ devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty"); class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); - strcpy(console_cdev.kobj.name, "dev.console"); 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) @@ -2451,11 +2445,7 @@ devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console"); class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); - tty_kobj.kset = tty_cdev.kobj.kset; - kobject_register(&tty_kobj); - #ifdef CONFIG_UNIX98_PTYS - strcpy(ptmx_cdev.kobj.name, "dev.ptmx"); cdev_init(&ptmx_cdev, &tty_fops); if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) @@ -2465,7 +2455,6 @@ #endif #ifdef CONFIG_VT - strcpy(vc0_cdev.kobj.name, "dev.vc0"); cdev_init(&vc0_cdev, &console_fops); if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) diff -Nru a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c --- a/drivers/ieee1394/amdtp.c Sun Mar 14 14:06:40 2004 +++ b/drivers/ieee1394/amdtp.c Sun Mar 14 14:06:40 2004 @@ -1266,7 +1266,6 @@ { cdev_init(&amdtp_cdev, &amdtp_fops); amdtp_cdev.owner = THIS_MODULE; - kobject_set_name(&amdtp_cdev.kobj, "amdtp"); if (cdev_add(&amdtp_cdev, IEEE1394_AMDTP_DEV, 16)) { HPSB_ERR("amdtp: unable to add char device"); return -EIO; diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c --- a/drivers/ieee1394/dv1394.c Sun Mar 14 14:06:40 2004 +++ b/drivers/ieee1394/dv1394.c Sun Mar 14 14:06:40 2004 @@ -2616,7 +2616,6 @@ cdev_init(&dv1394_cdev, &dv1394_fops); dv1394_cdev.owner = THIS_MODULE; - kobject_set_name(&dv1394_cdev.kobj, "dv1394"); ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); if (ret) { printk(KERN_ERR "dv1394: unable to register character device\n"); diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c --- a/drivers/ieee1394/raw1394.c Sun Mar 14 14:06:40 2004 +++ b/drivers/ieee1394/raw1394.c Sun Mar 14 14:06:40 2004 @@ -2746,9 +2746,9 @@ cdev_init(&raw1394_cdev, &raw1394_fops); raw1394_cdev.owner = THIS_MODULE; - kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME); ret = cdev_add(&raw1394_cdev, IEEE1394_RAW1394_DEV, 1); if (ret) { + /* jmc: leaves reference to (static) raw1394_cdev */ HPSB_ERR("raw1394 failed to register minor device block"); devfs_remove(RAW1394_DEVICE_NAME); hpsb_unregister_highlevel(&raw1394_highlevel); diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c --- a/drivers/ieee1394/video1394.c Sun Mar 14 14:06:40 2004 +++ b/drivers/ieee1394/video1394.c Sun Mar 14 14:06:40 2004 @@ -1457,7 +1457,6 @@ cdev_init(&video1394_cdev, &video1394_fops); video1394_cdev.owner = THIS_MODULE; - kobject_set_name(&video1394_cdev.kobj, VIDEO1394_DRIVER_NAME); ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16); if (ret) { PRINT_G(KERN_ERR, "video1394: unable to get minor device block"); diff -Nru a/drivers/input/input.c b/drivers/input/input.c --- a/drivers/input/input.c Sun Mar 14 14:06:40 2004 +++ b/drivers/input/input.c Sun Mar 14 14:06:40 2004 @@ -727,6 +727,8 @@ int retval = -ENOMEM; input_class = class_simple_create(THIS_MODULE, "input"); + if (IS_ERR(input_class)) + return PTR_ERR(input_class); input_proc_init(); retval = register_chrdev(INPUT_MAJOR, "input", &input_fops); if (retval) { @@ -734,6 +736,7 @@ remove_proc_entry("devices", proc_bus_input_dir); remove_proc_entry("handlers", proc_bus_input_dir); remove_proc_entry("input", proc_bus); + class_simple_destroy(input_class); return retval; } @@ -743,6 +746,7 @@ remove_proc_entry("handlers", proc_bus_input_dir); remove_proc_entry("input", proc_bus); unregister_chrdev(INPUT_MAJOR, "input"); + class_simple_destroy(input_class); } return retval; } diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c Sun Mar 14 14:06:40 2004 +++ b/drivers/net/ppp_generic.c Sun Mar 14 14:06:40 2004 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -271,6 +272,8 @@ static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); +static struct class_simple *ppp_class; + /* Translates a PPP protocol number to a NP index (NP == network protocol) */ static inline int proto_to_npindex(int proto) { @@ -804,15 +807,29 @@ printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); if (!err) { + ppp_class = class_simple_create(THIS_MODULE, "ppp"); + if (IS_ERR(ppp_class)) { + err = PTR_ERR(ppp_class); + goto out_chrdev; + } + class_simple_device_add(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "ppp"); if (err) - unregister_chrdev(PPP_MAJOR, "ppp"); + goto out_class; } +out: if (err) printk(KERN_ERR "failed to register PPP device (%d)\n", err); return err; + +out_class: + class_simple_device_remove(MKDEV(PPP_MAJOR,0)); + class_simple_destroy(ppp_class); +out_chrdev: + unregister_chrdev(PPP_MAJOR, "ppp"); + goto out; } /* @@ -2545,6 +2562,8 @@ if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) printk(KERN_ERR "PPP: failed to unregister PPP device\n"); devfs_remove("ppp"); + class_simple_device_remove(MKDEV(PPP_MAJOR, 0)); + class_simple_destroy(ppp_class); } /* diff -Nru a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c --- a/drivers/pci/hotplug/pci_hotplug_core.c Sun Mar 14 14:06:40 2004 +++ b/drivers/pci/hotplug/pci_hotplug_core.c Sun Mar 14 14:06:40 2004 @@ -104,19 +104,7 @@ .release = &hotplug_slot_release, }; -/* - * We create a struct subsystem on our own and not use decl_subsys so - * we can have a sane name "slots" in sysfs, yet still keep a good - * global variable name "pci_hotplug_slots_subsys. - * If the decl_subsys() #define ever changes, this declaration will - * need to be update to make sure everything is initialized properly. - */ -struct subsystem pci_hotplug_slots_subsys = { - .kset = { - .kobj = { .name = "slots" }, - .ktype = &hotplug_slot_ktype, - } -}; +decl_subsys_name(pci_hotplug_slots, slots, &hotplug_slot_ktype, NULL); /* these strings match up with the values in pci_bus_speed */ static char *pci_bus_speed_strings[] = { diff -Nru a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c --- a/drivers/s390/char/tape_class.c Sun Mar 14 14:06:40 2004 +++ b/drivers/s390/char/tape_class.c Sun Mar 14 14:06:40 2004 @@ -46,13 +46,10 @@ cdev->owner = fops->owner; cdev->ops = fops; cdev->dev = dev; - strcpy(cdev->kobj.name, devname); - for (s = strchr(cdev->kobj.name, '/'); s; s = strchr(s, '/')) - *s = '!'; rc = cdev_add(cdev, cdev->dev, 1); if (rc) { - kobject_put(&cdev->kobj); + cdev_del(cdev); return ERR_PTR(rc); } class_simple_device_add(tape_class, cdev->dev, device, "%s", devname); diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c --- a/drivers/scsi/sg.c Sun Mar 14 14:06:40 2004 +++ b/drivers/scsi/sg.c Sun Mar 14 14:06:40 2004 @@ -1409,7 +1409,6 @@ SCSI_LOG_TIMEOUT(3, printk("sg_add: dev=%d \n", k)); memset(sdp, 0, sizeof(*sdp)); sprintf(disk->disk_name, "sg%d", k); - strncpy(cdev->kobj.name, disk->disk_name, KOBJ_NAME_LEN); cdev->owner = THIS_MODULE; cdev->ops = &sg_fops; disk->major = SCSI_GENERIC_MAJOR; @@ -1439,7 +1438,7 @@ MKDEV(SCSI_GENERIC_MAJOR, k), cl_dev->dev, "%s", disk->disk_name); - if (NULL == sg_class_member) + if (IS_ERR(sg_class_member)) printk(KERN_WARNING "sg_add: " "class_simple_device_add failed\n"); class_set_devdata(sg_class_member, sdp); @@ -1462,7 +1461,7 @@ out: put_disk(disk); if (cdev) - kobject_put(&cdev->kobj); + cdev_del(cdev); return error; } diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c --- a/drivers/scsi/st.c Sun Mar 14 14:06:40 2004 +++ b/drivers/scsi/st.c Sun Mar 14 14:06:40 2004 @@ -3959,7 +3959,7 @@ } } if (cdev) - kobject_put(&cdev->kobj); + cdev_del(cdev); write_lock(&st_dev_arr_lock); scsi_tapes[dev_num] = NULL; st_nr_dev--; diff -Nru a/fs/char_dev.c b/fs/char_dev.c --- a/fs/char_dev.c Sun Mar 14 14:06:40 2004 +++ b/fs/char_dev.c Sun Mar 14 14:06:40 2004 @@ -340,15 +340,9 @@ int cdev_add(struct cdev *p, dev_t dev, unsigned count) { - int err = kobject_add(&p->kobj); - if (err) - return err; - err = kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); - if (err) - kobject_del(&p->kobj); p->dev = dev; p->count = count; - return err; + return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); } static void cdev_unmap(dev_t dev, unsigned count) @@ -359,7 +353,6 @@ void cdev_del(struct cdev *p) { cdev_unmap(p->dev, p->count); - kobject_del(&p->kobj); kobject_put(&p->kobj); } @@ -407,18 +400,12 @@ .release = cdev_dynamic_release, }; -static struct kset kset_dynamic = { - .subsys = &cdev_subsys, - .kobj = {.name = "major",}, - .ktype = &ktype_cdev_dynamic, -}; - struct cdev *cdev_alloc(void) { struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { memset(p, 0, sizeof(struct cdev)); - p->kobj.kset = &kset_dynamic; + p->kobj.ktype = &ktype_cdev_dynamic; INIT_LIST_HEAD(&p->list); kobject_init(&p->kobj); } @@ -428,7 +415,6 @@ void cdev_init(struct cdev *cdev, struct file_operations *fops) { INIT_LIST_HEAD(&cdev->list); - kobj_set_kset_s(cdev, cdev_subsys); cdev->kobj.ktype = &ktype_cdev_default; kobject_init(&cdev->kobj); cdev->ops = fops; @@ -444,8 +430,12 @@ void __init chrdev_init(void) { - subsystem_register(&cdev_subsys); - kset_register(&kset_dynamic); +/* + * Keep cdev_subsys around because (and only because) the kobj_map code + * depends on the rwsem it contains. We don't make it public in sysfs, + * however. + */ + subsystem_init(&cdev_subsys); cdev_map = kobj_map_init(base_probe, &cdev_subsys); } diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h --- a/include/linux/kobject.h Sun Mar 14 14:06:40 2004 +++ b/include/linux/kobject.h Sun Mar 14 14:06:40 2004 @@ -151,6 +151,14 @@ .hotplug_ops =_hotplug_ops, \ } \ } +#define decl_subsys_name(_varname,_name,_type,_hotplug_ops) \ +struct subsystem _varname##_subsys = { \ + .kset = { \ + .kobj = { .name = __stringify(_name) }, \ + .ktype = _type, \ + .hotplug_ops =_hotplug_ops, \ + } \ +} /** diff -Nru a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c --- a/net/netlink/netlink_dev.c Sun Mar 14 14:06:40 2004 +++ b/net/netlink/netlink_dev.c Sun Mar 14 14:06:40 2004 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ static long open_map; static struct socket *netlink_user[MAX_LINKS]; +static struct class_simple *netlink_class; /* * Device operations @@ -229,17 +231,26 @@ return -EIO; } + netlink_class = class_simple_create(THIS_MODULE, "netlink"); + if (IS_ERR(netlink_class)) { + printk (KERN_ERR "Error creating netlink class.\n"); + unregister_chrdev(NETLINK_MAJOR, "netlink"); + return PTR_ERR(netlink_class); + } + devfs_mk_dir("netlink"); /* Someone tell me the official names for the uppercase ones */ for (i = 0; i < ARRAY_SIZE(entries); i++) { devfs_mk_cdev(MKDEV(NETLINK_MAJOR, entries[i].minor), S_IFCHR|S_IRUSR|S_IWUSR, "netlink/%s", entries[i].name); + class_simple_device_add(netlink_class, MKDEV(NETLINK_MAJOR, entries[i].minor), NULL, "%s", entries[i].name); } for (i = 0; i < 16; i++) { devfs_mk_cdev(MKDEV(NETLINK_MAJOR, i + 16), S_IFCHR|S_IRUSR|S_IWUSR, "netlink/tap%d", i); + class_simple_device_add(netlink_class, MKDEV(NETLINK_MAJOR, i + 16), NULL, "tap%d", i); } return 0; @@ -249,11 +260,16 @@ { int i; - for (i = 0; i < ARRAY_SIZE(entries); i++) + for (i = 0; i < ARRAY_SIZE(entries); i++) { devfs_remove("netlink/%s", entries[i].name); - for (i = 0; i < 16; i++) + class_simple_device_remove(MKDEV(NETLINK_MAJOR, entries[i].minor)); + } + for (i = 0; i < 16; i++) { devfs_remove("netlink/tap%d", i); + class_simple_device_remove(MKDEV(NETLINK_MAJOR, i + 16)); + } devfs_remove("netlink"); + class_simple_destroy(netlink_class); unregister_chrdev(NETLINK_MAJOR, "netlink"); }