From e105b8bfc769b0545b6f0f395179d1e43cbee822 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 21 Apr 2008 10:51:07 -0700 Subject: sysfs: add /sys/dev/{char,block} to lookup sysfs path by major:minor Why?: There are occasions where userspace would like to access sysfs attributes for a device but it may not know how sysfs has named the device or the path. For example what is the sysfs path for /dev/disk/by-id/ata-ST3160827AS_5MT004CK? With this change a call to stat(2) returns the major:minor then userspace can see that /sys/dev/block/8:32 links to /sys/block/sdc. What are the alternatives?: 1/ Add an ioctl to return the path: Doable, but sysfs is meant to reduce the need to proliferate ioctl interfaces into the kernel, so this seems counter productive. 2/ Use udev to create these symlinks: Also doable, but it adds a udev dependency to utilities that might be running in a limited environment like an initramfs. 3/ Do a full-tree search of sysfs. [kay.sievers@vrfy.org: fix duplicate registrations] [kay.sievers@vrfy.org: cleanup suggestions] Cc: Neil Brown Cc: Tejun Heo Acked-by: Kay Sievers Reviewed-by: SL Baur Acked-by: Kay Sievers Acked-by: Mark Lord Acked-by: H. Peter Anvin Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/core.c b/drivers/base/core.c index ee0a51a3a41..be9aba4dc2f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -27,6 +27,9 @@ int (*platform_notify)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL; +static struct kobject *dev_kobj; +struct kobject *sysfs_dev_char_kobj; +struct kobject *sysfs_dev_block_kobj; #ifdef CONFIG_BLOCK static inline int device_is_not_partition(struct device *dev) @@ -775,6 +778,54 @@ int dev_set_name(struct device *dev, const char *fmt, ...) } EXPORT_SYMBOL_GPL(dev_set_name); +/** + * device_to_dev_kobj - select a /sys/dev/ directory for the device + * @dev: device + * + * By default we select char/ for new entries. Setting class->dev_obj + * to NULL prevents an entry from being created. class->dev_kobj must + * be set (or cleared) before any devices are registered to the class + * otherwise device_create_sys_dev_entry() and + * device_remove_sys_dev_entry() will disagree about the the presence + * of the link. + */ +static struct kobject *device_to_dev_kobj(struct device *dev) +{ + struct kobject *kobj; + + if (dev->class) + kobj = dev->class->dev_kobj; + else + kobj = sysfs_dev_char_kobj; + + return kobj; +} + +static int device_create_sys_dev_entry(struct device *dev) +{ + struct kobject *kobj = device_to_dev_kobj(dev); + int error = 0; + char devt_str[15]; + + if (kobj) { + format_dev_t(devt_str, dev->devt); + error = sysfs_create_link(kobj, &dev->kobj, devt_str); + } + + return error; +} + +static void device_remove_sys_dev_entry(struct device *dev) +{ + struct kobject *kobj = device_to_dev_kobj(dev); + char devt_str[15]; + + if (kobj) { + format_dev_t(devt_str, dev->devt); + sysfs_remove_link(kobj, devt_str); + } +} + /** * device_add - add device to device hierarchy. * @dev: device. @@ -829,6 +880,10 @@ int device_add(struct device *dev) error = device_create_file(dev, &devt_attr); if (error) goto ueventattrError; + + error = device_create_sys_dev_entry(dev); + if (error) + goto devtattrError; } error = device_add_class_symlinks(dev); @@ -872,6 +927,9 @@ int device_add(struct device *dev) AttrsError: device_remove_class_symlinks(dev); SymlinkError: + if (MAJOR(dev->devt)) + device_remove_sys_dev_entry(dev); + devtattrError: if (MAJOR(dev->devt)) device_remove_file(dev, &devt_attr); ueventattrError: @@ -948,8 +1006,10 @@ void device_del(struct device *dev) device_pm_remove(dev); if (parent) klist_del(&dev->knode_parent); - if (MAJOR(dev->devt)) + if (MAJOR(dev->devt)) { + device_remove_sys_dev_entry(dev); device_remove_file(dev, &devt_attr); + } if (dev->class) { device_remove_class_symlinks(dev); @@ -1074,7 +1134,25 @@ int __init devices_init(void) devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); if (!devices_kset) return -ENOMEM; + dev_kobj = kobject_create_and_add("dev", NULL); + if (!dev_kobj) + goto dev_kobj_err; + sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj); + if (!sysfs_dev_block_kobj) + goto block_kobj_err; + sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); + if (!sysfs_dev_char_kobj) + goto char_kobj_err; + return 0; + + char_kobj_err: + kobject_put(sysfs_dev_block_kobj); + block_kobj_err: + kobject_put(dev_kobj); + dev_kobj_err: + kset_unregister(devices_kset); + return -ENOMEM; } EXPORT_SYMBOL_GPL(device_for_each_child); @@ -1447,4 +1525,7 @@ void device_shutdown(void) dev->driver->shutdown(dev); } } + kobject_put(sysfs_dev_char_kobj); + kobject_put(sysfs_dev_block_kobj); + kobject_put(dev_kobj); } -- cgit v1.2.3-70-g09d2 From ccea44fadca396b0f89aed5bdeb60e4abb212566 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 21 May 2008 12:52:33 -0700 Subject: driver core: remove device_create() There are no more users of this, and it is racy. Use device_create_drvdata() or device_create_vargs() instead. Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 34 ---------------------------------- include/linux/device.h | 3 --- 2 files changed, 37 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/core.c b/drivers/base/core.c index be9aba4dc2f..4dc0d272f6d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1273,40 +1273,6 @@ struct device *device_create_drvdata(struct class *class, } EXPORT_SYMBOL_GPL(device_create_drvdata); -/** - * device_create - creates a device and registers it with sysfs - * @class: pointer to the struct class that this device should be registered to - * @parent: pointer to the parent struct device of this new device, if any - * @devt: the dev_t for the char device to be added - * @fmt: string for the device's name - * - * This function can be used by char device classes. A struct device - * will be created in sysfs, registered to the specified 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 device is passed in, the newly created - * struct device will be a child of that device in sysfs. - * The pointer to the struct 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 device *device_create(struct class *class, struct device *parent, - dev_t devt, const char *fmt, ...) -{ - va_list vargs; - struct device *dev; - - va_start(vargs, fmt); - dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs); - va_end(vargs); - return dev; -} -EXPORT_SYMBOL_GPL(device_create); - static int __match_devt(struct device *dev, void *data) { dev_t *devt = data; diff --git a/include/linux/device.h b/include/linux/device.h index e49aa74f248..a3ef5a2d4fb 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -470,9 +470,6 @@ extern struct device *device_create_vargs(struct class *cls, void *drvdata, const char *fmt, va_list vargs); -extern struct device *device_create(struct class *cls, struct device *parent, - dev_t devt, const char *fmt, ...) - __attribute__((format(printf, 4, 5))); extern struct device *device_create_drvdata(struct class *cls, struct device *parent, dev_t devt, -- cgit v1.2.3-70-g09d2 From 4e10673944a5c386378ff9d692ae37e19993f9d5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Jul 2008 20:03:34 -0700 Subject: device create: convert device_create_drvdata to device_create Now that device_create() has been audited, rename things back to the original call to be sane. Keep the device_create_drvdata macro around to make merges easier. Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 11 ++++------- include/linux/device.h | 9 ++++----- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/core.c b/drivers/base/core.c index 4dc0d272f6d..9ae28aa709d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1236,7 +1236,7 @@ error: EXPORT_SYMBOL_GPL(device_create_vargs); /** - * device_create_drvdata - creates a device and registers it with sysfs + * device_create - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added @@ -1257,11 +1257,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs); * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ -struct device *device_create_drvdata(struct class *class, - struct device *parent, - dev_t devt, - void *drvdata, - const char *fmt, ...) +struct device *device_create(struct class *class, struct device *parent, + dev_t devt, void *drvdata, const char *fmt, ...) { va_list vargs; struct device *dev; @@ -1271,7 +1268,7 @@ struct device *device_create_drvdata(struct class *class, va_end(vargs); return dev; } -EXPORT_SYMBOL_GPL(device_create_drvdata); +EXPORT_SYMBOL_GPL(device_create); static int __match_devt(struct device *dev, void *data) { diff --git a/include/linux/device.h b/include/linux/device.h index a3ef5a2d4fb..de178712e02 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -470,12 +470,11 @@ extern struct device *device_create_vargs(struct class *cls, void *drvdata, const char *fmt, va_list vargs); -extern struct device *device_create_drvdata(struct class *cls, - struct device *parent, - dev_t devt, - void *drvdata, - const char *fmt, ...) +extern struct device *device_create(struct class *cls, struct device *parent, + dev_t devt, void *drvdata, + const char *fmt, ...) __attribute__((format(printf, 5, 6))); +#define device_create_drvdata device_create extern void device_destroy(struct class *cls, dev_t devt); /* -- cgit v1.2.3-70-g09d2 From 695794ae0c5bdd9bd06e35b118801e2e9be04f9e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 22 May 2008 17:21:08 -0400 Subject: Driver Core: add ability for class_find_device to start in middle of list This mirrors the functionality that driver_find_device has as well. We add a start variable, and all callers of the function are fixed up at the same time. The block layer will be using this new functionality in a follow-on patch. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 22 +++++++++++++--------- drivers/base/core.c | 2 +- drivers/ieee1394/nodemgr.c | 9 ++++++--- drivers/rtc/interface.c | 2 +- drivers/scsi/hosts.c | 3 ++- drivers/scsi/scsi_transport_iscsi.c | 4 ++-- drivers/spi/spi.c | 2 +- include/linux/device.h | 3 ++- 8 files changed, 28 insertions(+), 19 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/class.c b/drivers/base/class.c index 2eb7048003a..3918d0e432d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -302,6 +302,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device); /** * class_find_device - device iterator for locating a particular device * @class: the class we're iterating + * @start: Device to begin with * @data: data for the match function * @match: function to check device * @@ -319,8 +320,9 @@ EXPORT_SYMBOL_GPL(class_for_each_device); * re-acquired in @match, otherwise it will self-deadlocking. For * example, calls to add or remove class members would be verboten. */ -struct device *class_find_device(struct class *class, void *data, - int (*match)(struct device *, void *)) +struct device *class_find_device(struct class *class, struct device *start, + void *data, + int (*match)(struct device *, void *)) { struct device *dev; int found = 0; @@ -330,15 +332,17 @@ struct device *class_find_device(struct class *class, void *data, down(&class->sem); list_for_each_entry(dev, &class->devices, node) { + if (start) { + if (start == dev) + start = NULL; + continue; + } dev = get_device(dev); - if (dev) { - if (match(dev, data)) { - found = 1; - break; - } else - put_device(dev); - } else + if (match(dev, data)) { + found = 1; break; + } else + put_device(dev); } up(&class->sem); diff --git a/drivers/base/core.c b/drivers/base/core.c index 9ae28aa709d..9f05de6f80b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1289,7 +1289,7 @@ void device_destroy(struct class *class, dev_t devt) { struct device *dev; - dev = class_find_device(class, &devt, __match_devt); + dev = class_find_device(class, NULL, &devt, __match_devt); if (dev) { put_device(dev); device_unregister(dev); diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 47c0d85e0f3..994a21e5a0a 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -754,7 +754,8 @@ static void nodemgr_remove_uds(struct node_entry *ne) */ mutex_lock(&nodemgr_serialize_remove_uds); for (;;) { - dev = class_find_device(&nodemgr_ud_class, ne, __match_ne); + dev = class_find_device(&nodemgr_ud_class, NULL, ne, + __match_ne); if (!dev) break; ud = container_of(dev, struct unit_directory, unit_dev); @@ -901,7 +902,8 @@ static struct node_entry *find_entry_by_guid(u64 guid) struct device *dev; struct node_entry *ne; - dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid); + dev = class_find_device(&nodemgr_ne_class, NULL, &guid, + __match_ne_guid); if (!dev) return NULL; ne = container_of(dev, struct node_entry, node_dev); @@ -940,7 +942,8 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, param.host = host; param.nodeid = nodeid; - dev = class_find_device(&nodemgr_ne_class, ¶m, __match_ne_nodeid); + dev = class_find_device(&nodemgr_ne_class, NULL, ¶m, + __match_ne_nodeid); if (!dev) return NULL; ne = container_of(dev, struct node_entry, node_dev); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 58b7336640f..d397fa5f3a9 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -345,7 +345,7 @@ struct rtc_device *rtc_class_open(char *name) struct device *dev; struct rtc_device *rtc = NULL; - dev = class_find_device(rtc_class, name, __rtc_match); + dev = class_find_device(rtc_class, NULL, name, __rtc_match); if (dev) rtc = to_rtc_device(dev); diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 35cd892dce0..78dad28b70d 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -466,7 +466,8 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) struct device *cdev; struct Scsi_Host *shost = ERR_PTR(-ENXIO); - cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match); + cdev = class_find_device(&shost_class, NULL, &hostnum, + __scsi_host_match); if (cdev) { shost = scsi_host_get(class_to_shost(cdev)); put_device(cdev); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 3af7cbcc5c5..06748f318cd 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -170,7 +170,7 @@ iscsi_create_endpoint(int dd_size) int err; for (id = 1; id < ISCSI_MAX_EPID; id++) { - dev = class_find_device(&iscsi_endpoint_class, &id, + dev = class_find_device(&iscsi_endpoint_class, NULL, &id, iscsi_match_epid); if (!dev) break; @@ -222,7 +222,7 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) struct iscsi_endpoint *ep; struct device *dev; - dev = class_find_device(&iscsi_endpoint_class, &handle, + dev = class_find_device(&iscsi_endpoint_class, NULL, &handle, iscsi_match_epid); if (!dev) return NULL; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1ad12afc6ba..1771b2456bf 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -502,7 +502,7 @@ struct spi_master *spi_busnum_to_master(u16 bus_num) struct device *dev; struct spi_master *master = NULL; - dev = class_find_device(&spi_master_class, &bus_num, + dev = class_find_device(&spi_master_class, NULL, &bus_num, __spi_master_match); if (dev) master = container_of(dev, struct spi_master, dev); diff --git a/include/linux/device.h b/include/linux/device.h index 6d5b351b29c..c1f72984875 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -213,7 +213,8 @@ extern void class_unregister(struct class *class); extern int class_for_each_device(struct class *class, struct device *start, void *data, int (*fn)(struct device *dev, void *data)); -extern struct device *class_find_device(struct class *class, void *data, +extern struct device *class_find_device(struct class *class, + struct device *start, void *data, int (*match)(struct device *, void *)); struct class_attribute { -- cgit v1.2.3-70-g09d2 From 7c71448b8aa80123fc521563d5f7c63a099d97ab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2008 18:17:41 -0500 Subject: class: move driver core specific parts to a private structure This moves the portions of struct class that are dynamic (kobject and lock and lists) out of the main structure and into a dynamic, private, structure. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 27 ++++++++++++++++ drivers/base/class.c | 87 ++++++++++++++++++++++++++++---------------------- drivers/base/core.c | 57 +++++++++++++++++---------------- include/linux/device.h | 7 ++-- 4 files changed, 107 insertions(+), 71 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/base.h b/drivers/base/base.h index 2c9ae43e221..0ec372a6776 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -36,6 +36,33 @@ struct driver_private { }; #define to_driver(obj) container_of(obj, struct driver_private, kobj) + +/** + * struct class_private - structure to hold the private to the driver core portions of the class structure. + * + * @subsys - the struct kset that defines this class. This is the main kobject + * @children - list of class_devices associated with this class + * @devices - list of devices associated with this class + * @interfaces - list of class_interfaces associated with this class + * @class_dirs - + * @sem - semaphore to protect the children, devices, and interfaces lists. + * @class - pointer back to the struct class that this structure is associated + * with. + * + * This structure is the one that is the actual kobject allowing struct + * class to be statically allocated safely. Nothing outside of the driver + * core should ever touch these fields. + */ +struct class_private { + struct kset subsys; + struct list_head devices; + struct list_head interfaces; + struct kset class_dirs; + struct semaphore sem; + struct class *class; +}; +#define to_class(obj) container_of(obj, struct class_private, subsys.kobj) + /* initialisation functions */ extern int devices_init(void); extern int buses_init(void); diff --git a/drivers/base/class.c b/drivers/base/class.c index 3918d0e432d..06f09c929a9 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -21,17 +21,16 @@ #include "base.h" #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) -#define to_class(obj) container_of(obj, struct class, subsys.kobj) static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct class_attribute *class_attr = to_class_attr(attr); - struct class *dc = to_class(kobj); + struct class_private *cp = to_class(kobj); ssize_t ret = -EIO; if (class_attr->show) - ret = class_attr->show(dc, buf); + ret = class_attr->show(cp->class, buf); return ret; } @@ -39,17 +38,18 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { struct class_attribute *class_attr = to_class_attr(attr); - struct class *dc = to_class(kobj); + struct class_private *cp = to_class(kobj); ssize_t ret = -EIO; if (class_attr->store) - ret = class_attr->store(dc, buf, count); + ret = class_attr->store(cp->class, buf, count); return ret; } static void class_release(struct kobject *kobj) { - struct class *class = to_class(kobj); + struct class_private *cp = to_class(kobj); + struct class *class = cp->class; pr_debug("class '%s': release.\n", class->name); @@ -78,7 +78,7 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) { int error; if (cls) - error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); + error = sysfs_create_file(&cls->p->subsys.kobj, &attr->attr); else error = -EINVAL; return error; @@ -87,21 +87,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) void class_remove_file(struct class *cls, const struct class_attribute *attr) { if (cls) - sysfs_remove_file(&cls->subsys.kobj, &attr->attr); + sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr); } static struct class *class_get(struct class *cls) { if (cls) - return container_of(kset_get(&cls->subsys), - struct class, subsys); - return NULL; + kset_get(&cls->p->subsys); + return cls; } static void class_put(struct class *cls) { if (cls) - kset_put(&cls->subsys); + kset_put(&cls->p->subsys); } static int add_class_attrs(struct class *cls) @@ -136,17 +135,23 @@ static void remove_class_attrs(struct class *cls) int class_register(struct class *cls) { + struct class_private *cp; int error; pr_debug("device class '%s': registering\n", cls->name); - INIT_LIST_HEAD(&cls->devices); - INIT_LIST_HEAD(&cls->interfaces); - kset_init(&cls->class_dirs); - init_MUTEX(&cls->sem); - error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name); - if (error) + cp = kzalloc(sizeof(*cp), GFP_KERNEL); + if (!cp) + return -ENOMEM; + INIT_LIST_HEAD(&cp->devices); + INIT_LIST_HEAD(&cp->interfaces); + kset_init(&cp->class_dirs); + init_MUTEX(&cp->sem); + error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); + if (error) { + kfree(cp); return error; + } /* set the default /sys/dev directory for devices of this class */ if (!cls->dev_kobj) @@ -155,17 +160,21 @@ int class_register(struct class *cls) #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) /* let the block class directory show up in the root of sysfs */ if (cls != &block_class) - cls->subsys.kobj.kset = class_kset; + cp->subsys.kobj.kset = class_kset; #else - cls->subsys.kobj.kset = class_kset; + cp->subsys.kobj.kset = class_kset; #endif - cls->subsys.kobj.ktype = &class_ktype; + cp->subsys.kobj.ktype = &class_ktype; + cp->class = cls; + cls->p = cp; - error = kset_register(&cls->subsys); - if (!error) { - error = add_class_attrs(class_get(cls)); - class_put(cls); + error = kset_register(&cp->subsys); + if (error) { + kfree(cp); + return error; } + error = add_class_attrs(class_get(cls)); + class_put(cls); return error; } @@ -173,7 +182,7 @@ void class_unregister(struct class *cls) { pr_debug("device class '%s': unregistering\n", cls->name); remove_class_attrs(cls); - kset_unregister(&cls->subsys); + kset_unregister(&cls->p->subsys); } static void class_create_release(struct class *cls) @@ -280,8 +289,8 @@ int class_for_each_device(struct class *class, struct device *start, if (!class) return -EINVAL; - down(&class->sem); - list_for_each_entry(dev, &class->devices, node) { + down(&class->p->sem); + list_for_each_entry(dev, &class->p->devices, node) { if (start) { if (start == dev) start = NULL; @@ -293,7 +302,7 @@ int class_for_each_device(struct class *class, struct device *start, if (error) break; } - up(&class->sem); + up(&class->p->sem); return error; } @@ -330,8 +339,8 @@ struct device *class_find_device(struct class *class, struct device *start, if (!class) return NULL; - down(&class->sem); - list_for_each_entry(dev, &class->devices, node) { + down(&class->p->sem); + list_for_each_entry(dev, &class->p->devices, node) { if (start) { if (start == dev) start = NULL; @@ -344,7 +353,7 @@ struct device *class_find_device(struct class *class, struct device *start, } else put_device(dev); } - up(&class->sem); + up(&class->p->sem); return found ? dev : NULL; } @@ -362,13 +371,13 @@ int class_interface_register(struct class_interface *class_intf) if (!parent) return -EINVAL; - down(&parent->sem); - list_add_tail(&class_intf->node, &parent->interfaces); + down(&parent->p->sem); + list_add_tail(&class_intf->node, &parent->p->interfaces); if (class_intf->add_dev) { - list_for_each_entry(dev, &parent->devices, node) + list_for_each_entry(dev, &parent->p->devices, node) class_intf->add_dev(dev, class_intf); } - up(&parent->sem); + up(&parent->p->sem); return 0; } @@ -381,13 +390,13 @@ void class_interface_unregister(struct class_interface *class_intf) if (!parent) return; - down(&parent->sem); + down(&parent->p->sem); list_del_init(&class_intf->node); if (class_intf->remove_dev) { - list_for_each_entry(dev, &parent->devices, node) + list_for_each_entry(dev, &parent->p->devices, node) class_intf->remove_dev(dev, class_intf); } - up(&parent->sem); + up(&parent->p->sem); class_put(parent); } diff --git a/drivers/base/core.c b/drivers/base/core.c index 9f05de6f80b..64c150b5a88 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -551,7 +551,7 @@ static struct kobject *get_device_parent(struct device *dev, { /* class devices without a parent live in /sys/class// */ if (dev->class && (!parent || parent->class != dev->class)) - return &dev->class->subsys.kobj; + return &dev->class->p->subsys.kobj; /* all other devices keep their parent */ else if (parent) return &parent->kobj; @@ -597,13 +597,13 @@ static struct kobject *get_device_parent(struct device *dev, parent_kobj = &parent->kobj; /* find our class-directory at the parent and reference it */ - spin_lock(&dev->class->class_dirs.list_lock); - list_for_each_entry(k, &dev->class->class_dirs.list, entry) + spin_lock(&dev->class->p->class_dirs.list_lock); + list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) if (k->parent == parent_kobj) { kobj = kobject_get(k); break; } - spin_unlock(&dev->class->class_dirs.list_lock); + spin_unlock(&dev->class->p->class_dirs.list_lock); if (kobj) return kobj; @@ -611,7 +611,7 @@ static struct kobject *get_device_parent(struct device *dev, k = kobject_create(); if (!k) return NULL; - k->kset = &dev->class->class_dirs; + k->kset = &dev->class->p->class_dirs; retval = kobject_add(k, parent_kobj, "%s", dev->class->name); if (retval < 0) { kobject_put(k); @@ -630,7 +630,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) { /* see if we live in a "glue" directory */ if (!glue_dir || !dev->class || - glue_dir->kset != &dev->class->class_dirs) + glue_dir->kset != &dev->class->p->class_dirs) return; kobject_put(glue_dir); @@ -657,17 +657,17 @@ static int device_add_class_symlinks(struct device *dev) if (!dev->class) return 0; - error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, + error = sysfs_create_link(&dev->kobj, &dev->class->p->subsys.kobj, "subsystem"); if (error) goto out; #ifdef CONFIG_SYSFS_DEPRECATED /* stacked class devices need a symlink in the class directory */ - if (dev->kobj.parent != &dev->class->subsys.kobj && + if (dev->kobj.parent != &dev->class->p->subsys.kobj && device_is_not_partition(dev)) { - error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, - dev->bus_id); + error = sysfs_create_link(&dev->class->p->subsys.kobj, + &dev->kobj, dev->bus_id); if (error) goto out_subsys; } @@ -704,12 +704,12 @@ out_device: if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); out_busid: - if (dev->kobj.parent != &dev->class->subsys.kobj && + if (dev->kobj.parent != &dev->class->p->subsys.kobj && device_is_not_partition(dev)) - sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); #else /* link in the class directory pointing to the device */ - error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, + error = sysfs_create_link(&dev->class->p->subsys.kobj, &dev->kobj, dev->bus_id); if (error) goto out_subsys; @@ -723,7 +723,7 @@ out_busid: return 0; out_busid: - sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); #endif out_subsys: @@ -749,14 +749,14 @@ static void device_remove_class_symlinks(struct device *dev) sysfs_remove_link(&dev->kobj, "device"); } - if (dev->kobj.parent != &dev->class->subsys.kobj && + if (dev->kobj.parent != &dev->class->p->subsys.kobj && device_is_not_partition(dev)) - sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); #else if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); - sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); #endif sysfs_remove_link(&dev->kobj, "subsystem"); @@ -904,15 +904,16 @@ int device_add(struct device *dev) klist_add_tail(&dev->knode_parent, &parent->klist_children); if (dev->class) { - down(&dev->class->sem); + down(&dev->class->p->sem); /* tie the class to the device */ - list_add_tail(&dev->node, &dev->class->devices); + list_add_tail(&dev->node, &dev->class->p->devices); /* notify any interfaces that the device is here */ - list_for_each_entry(class_intf, &dev->class->interfaces, node) + list_for_each_entry(class_intf, &dev->class->p->interfaces, + node) if (class_intf->add_dev) class_intf->add_dev(dev, class_intf); - up(&dev->class->sem); + up(&dev->class->p->sem); } Done: put_device(dev); @@ -1013,14 +1014,15 @@ void device_del(struct device *dev) if (dev->class) { device_remove_class_symlinks(dev); - down(&dev->class->sem); + down(&dev->class->p->sem); /* notify any interfaces that the device is now gone */ - list_for_each_entry(class_intf, &dev->class->interfaces, node) + list_for_each_entry(class_intf, &dev->class->p->interfaces, + node) if (class_intf->remove_dev) class_intf->remove_dev(dev, class_intf); /* remove the device from the class list */ list_del_init(&dev->node); - up(&dev->class->sem); + up(&dev->class->p->sem); } device_remove_file(dev, &uevent_attr); device_remove_attrs(dev); @@ -1348,11 +1350,12 @@ int device_rename(struct device *dev, char *new_name) } #else if (dev->class) { - error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, - dev->bus_id); + error = sysfs_create_link(&dev->class->p->subsys.kobj, + &dev->kobj, dev->bus_id); if (error) goto out; - sysfs_remove_link(&dev->class->subsys.kobj, old_device_name); + sysfs_remove_link(&dev->class->p->subsys.kobj, + old_device_name); } #endif diff --git a/include/linux/device.h b/include/linux/device.h index c1f72984875..b0556082179 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -35,6 +35,7 @@ struct device; struct device_driver; struct driver_private; struct class; +struct class_private; struct bus_type; struct bus_type_private; @@ -186,11 +187,6 @@ struct class { const char *name; struct module *owner; - struct kset subsys; - struct list_head devices; - struct list_head interfaces; - struct kset class_dirs; - struct semaphore sem; /* locks children, devices, interfaces */ struct class_attribute *class_attrs; struct device_attribute *dev_attrs; struct kobject *dev_kobj; @@ -204,6 +200,7 @@ struct class { int (*resume)(struct device *dev); struct pm_ops *pm; + struct class_private *p; }; extern struct kobject *sysfs_dev_block_kobj; -- cgit v1.2.3-70-g09d2 From 97ae69fdbaa71a8f7dbc20bf10fb349d1759152f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 May 2008 09:28:39 -0700 Subject: class: rename "devices" to "class_devices" in internal class structure This renames the struct class "devices" field to be "class_devices" to make things easier when struct bus_type and struct class merge in the future. It also makes grepping for fields easier as well. Based on an idea from Kay. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 4 ++-- drivers/base/class.c | 10 +++++----- drivers/base/core.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/base.h b/drivers/base/base.h index 0ec372a6776..586c4ca7025 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -42,7 +42,7 @@ struct driver_private { * * @subsys - the struct kset that defines this class. This is the main kobject * @children - list of class_devices associated with this class - * @devices - list of devices associated with this class + * @class_devices - list of devices associated with this class * @interfaces - list of class_interfaces associated with this class * @class_dirs - * @sem - semaphore to protect the children, devices, and interfaces lists. @@ -55,7 +55,7 @@ struct driver_private { */ struct class_private { struct kset subsys; - struct list_head devices; + struct list_head class_devices; struct list_head interfaces; struct kset class_dirs; struct semaphore sem; diff --git a/drivers/base/class.c b/drivers/base/class.c index 06f09c929a9..9947560def6 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -143,7 +143,7 @@ int class_register(struct class *cls) cp = kzalloc(sizeof(*cp), GFP_KERNEL); if (!cp) return -ENOMEM; - INIT_LIST_HEAD(&cp->devices); + INIT_LIST_HEAD(&cp->class_devices); INIT_LIST_HEAD(&cp->interfaces); kset_init(&cp->class_dirs); init_MUTEX(&cp->sem); @@ -290,7 +290,7 @@ int class_for_each_device(struct class *class, struct device *start, if (!class) return -EINVAL; down(&class->p->sem); - list_for_each_entry(dev, &class->p->devices, node) { + list_for_each_entry(dev, &class->p->class_devices, node) { if (start) { if (start == dev) start = NULL; @@ -340,7 +340,7 @@ struct device *class_find_device(struct class *class, struct device *start, return NULL; down(&class->p->sem); - list_for_each_entry(dev, &class->p->devices, node) { + list_for_each_entry(dev, &class->p->class_devices, node) { if (start) { if (start == dev) start = NULL; @@ -374,7 +374,7 @@ int class_interface_register(struct class_interface *class_intf) down(&parent->p->sem); list_add_tail(&class_intf->node, &parent->p->interfaces); if (class_intf->add_dev) { - list_for_each_entry(dev, &parent->p->devices, node) + list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->add_dev(dev, class_intf); } up(&parent->p->sem); @@ -393,7 +393,7 @@ void class_interface_unregister(struct class_interface *class_intf) down(&parent->p->sem); list_del_init(&class_intf->node); if (class_intf->remove_dev) { - list_for_each_entry(dev, &parent->p->devices, node) + list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->remove_dev(dev, class_intf); } up(&parent->p->sem); diff --git a/drivers/base/core.c b/drivers/base/core.c index 64c150b5a88..52d1e71f2a4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -906,7 +906,7 @@ int device_add(struct device *dev) if (dev->class) { down(&dev->class->p->sem); /* tie the class to the device */ - list_add_tail(&dev->node, &dev->class->p->devices); + list_add_tail(&dev->node, &dev->class->p->class_devices); /* notify any interfaces that the device is here */ list_for_each_entry(class_intf, &dev->class->p->interfaces, -- cgit v1.2.3-70-g09d2 From 184f1f779d5a2e62de4a0b34842ddf8546beca8f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 May 2008 09:28:39 -0700 Subject: class: rename "interfaces" to "class_interfaces" in internal class structure This renames the struct class "interfaces" field to be "class_interfaces" to make things easier when struct bus_type and struct class merge in the future. It also makes grepping for fields easier as well. Based on an idea from Kay. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 4 ++-- drivers/base/class.c | 4 ++-- drivers/base/core.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/base.h b/drivers/base/base.h index 586c4ca7025..670b95a1a51 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -43,7 +43,7 @@ struct driver_private { * @subsys - the struct kset that defines this class. This is the main kobject * @children - list of class_devices associated with this class * @class_devices - list of devices associated with this class - * @interfaces - list of class_interfaces associated with this class + * @class_interfaces - list of class_interfaces associated with this class * @class_dirs - * @sem - semaphore to protect the children, devices, and interfaces lists. * @class - pointer back to the struct class that this structure is associated @@ -56,7 +56,7 @@ struct driver_private { struct class_private { struct kset subsys; struct list_head class_devices; - struct list_head interfaces; + struct list_head class_interfaces; struct kset class_dirs; struct semaphore sem; struct class *class; diff --git a/drivers/base/class.c b/drivers/base/class.c index 9947560def6..48b518e66bf 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -144,7 +144,7 @@ int class_register(struct class *cls) if (!cp) return -ENOMEM; INIT_LIST_HEAD(&cp->class_devices); - INIT_LIST_HEAD(&cp->interfaces); + INIT_LIST_HEAD(&cp->class_interfaces); kset_init(&cp->class_dirs); init_MUTEX(&cp->sem); error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); @@ -372,7 +372,7 @@ int class_interface_register(struct class_interface *class_intf) return -EINVAL; down(&parent->p->sem); - list_add_tail(&class_intf->node, &parent->p->interfaces); + list_add_tail(&class_intf->node, &parent->p->class_interfaces); if (class_intf->add_dev) { list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->add_dev(dev, class_intf); diff --git a/drivers/base/core.c b/drivers/base/core.c index 52d1e71f2a4..76fdd41fea0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -909,8 +909,8 @@ int device_add(struct device *dev) list_add_tail(&dev->node, &dev->class->p->class_devices); /* notify any interfaces that the device is here */ - list_for_each_entry(class_intf, &dev->class->p->interfaces, - node) + list_for_each_entry(class_intf, + &dev->class->p->class_interfaces, node) if (class_intf->add_dev) class_intf->add_dev(dev, class_intf); up(&dev->class->p->sem); @@ -1016,8 +1016,8 @@ void device_del(struct device *dev) down(&dev->class->p->sem); /* notify any interfaces that the device is now gone */ - list_for_each_entry(class_intf, &dev->class->p->interfaces, - node) + list_for_each_entry(class_intf, + &dev->class->p->class_interfaces, node) if (class_intf->remove_dev) class_intf->remove_dev(dev, class_intf); /* remove the device from the class list */ -- cgit v1.2.3-70-g09d2 From 1fbfee6c6dc0f4a4c587b6b163ee79643fc9aaa7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 May 2008 09:28:39 -0700 Subject: class: rename "subsys" to "class_subsys" in internal class structure This renames the struct class "subsys" field to be "class_subsys" to make things easier when struct bus_type and struct class merge in the future. It also makes grepping for fields easier as well. Based on an idea from Kay. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 7 ++++--- drivers/base/class.c | 23 ++++++++++++----------- drivers/base/core.c | 31 +++++++++++++++++-------------- 3 files changed, 33 insertions(+), 28 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/base.h b/drivers/base/base.h index 670b95a1a51..a77d4bd2ea6 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -40,7 +40,7 @@ struct driver_private { /** * struct class_private - structure to hold the private to the driver core portions of the class structure. * - * @subsys - the struct kset that defines this class. This is the main kobject + * @class_subsys - the struct kset that defines this class. This is the main kobject * @children - list of class_devices associated with this class * @class_devices - list of devices associated with this class * @class_interfaces - list of class_interfaces associated with this class @@ -54,14 +54,15 @@ struct driver_private { * core should ever touch these fields. */ struct class_private { - struct kset subsys; + struct kset class_subsys; struct list_head class_devices; struct list_head class_interfaces; struct kset class_dirs; struct semaphore sem; struct class *class; }; -#define to_class(obj) container_of(obj, struct class_private, subsys.kobj) +#define to_class(obj) \ + container_of(obj, struct class_private, class_subsys.kobj) /* initialisation functions */ extern int devices_init(void); diff --git a/drivers/base/class.c b/drivers/base/class.c index 48b518e66bf..86778b86496 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -70,7 +70,7 @@ static struct kobj_type class_ktype = { .release = class_release, }; -/* Hotplug events for classes go to the class_obj subsys */ +/* Hotplug events for classes go to the class class_subsys */ static struct kset *class_kset; @@ -78,7 +78,8 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) { int error; if (cls) - error = sysfs_create_file(&cls->p->subsys.kobj, &attr->attr); + error = sysfs_create_file(&cls->p->class_subsys.kobj, + &attr->attr); else error = -EINVAL; return error; @@ -87,20 +88,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) void class_remove_file(struct class *cls, const struct class_attribute *attr) { if (cls) - sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr); + sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr); } static struct class *class_get(struct class *cls) { if (cls) - kset_get(&cls->p->subsys); + kset_get(&cls->p->class_subsys); return cls; } static void class_put(struct class *cls) { if (cls) - kset_put(&cls->p->subsys); + kset_put(&cls->p->class_subsys); } static int add_class_attrs(struct class *cls) @@ -147,7 +148,7 @@ int class_register(struct class *cls) INIT_LIST_HEAD(&cp->class_interfaces); kset_init(&cp->class_dirs); init_MUTEX(&cp->sem); - error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); + error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); if (error) { kfree(cp); return error; @@ -160,15 +161,15 @@ int class_register(struct class *cls) #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) /* let the block class directory show up in the root of sysfs */ if (cls != &block_class) - cp->subsys.kobj.kset = class_kset; + cp->class_subsys.kobj.kset = class_kset; #else - cp->subsys.kobj.kset = class_kset; + cp->class_subsys.kobj.kset = class_kset; #endif - cp->subsys.kobj.ktype = &class_ktype; + cp->class_subsys.kobj.ktype = &class_ktype; cp->class = cls; cls->p = cp; - error = kset_register(&cp->subsys); + error = kset_register(&cp->class_subsys); if (error) { kfree(cp); return error; @@ -182,7 +183,7 @@ void class_unregister(struct class *cls) { pr_debug("device class '%s': unregistering\n", cls->name); remove_class_attrs(cls); - kset_unregister(&cls->p->subsys); + kset_unregister(&cls->p->class_subsys); } static void class_create_release(struct class *cls) diff --git a/drivers/base/core.c b/drivers/base/core.c index 76fdd41fea0..6e1cff296d9 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -551,7 +551,7 @@ static struct kobject *get_device_parent(struct device *dev, { /* class devices without a parent live in /sys/class// */ if (dev->class && (!parent || parent->class != dev->class)) - return &dev->class->p->subsys.kobj; + return &dev->class->p->class_subsys.kobj; /* all other devices keep their parent */ else if (parent) return &parent->kobj; @@ -657,16 +657,17 @@ static int device_add_class_symlinks(struct device *dev) if (!dev->class) return 0; - error = sysfs_create_link(&dev->kobj, &dev->class->p->subsys.kobj, + error = sysfs_create_link(&dev->kobj, + &dev->class->p->class_subsys.kobj, "subsystem"); if (error) goto out; #ifdef CONFIG_SYSFS_DEPRECATED /* stacked class devices need a symlink in the class directory */ - if (dev->kobj.parent != &dev->class->p->subsys.kobj && + if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && device_is_not_partition(dev)) { - error = sysfs_create_link(&dev->class->p->subsys.kobj, + error = sysfs_create_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev->bus_id); if (error) goto out_subsys; @@ -704,13 +705,14 @@ out_device: if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); out_busid: - if (dev->kobj.parent != &dev->class->p->subsys.kobj && + if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && device_is_not_partition(dev)) - sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->class_subsys.kobj, + dev->bus_id); #else /* link in the class directory pointing to the device */ - error = sysfs_create_link(&dev->class->p->subsys.kobj, &dev->kobj, - dev->bus_id); + error = sysfs_create_link(&dev->class->p->class_subsys.kobj, + &dev->kobj, dev->bus_id); if (error) goto out_subsys; @@ -723,7 +725,7 @@ out_busid: return 0; out_busid: - sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id); #endif out_subsys: @@ -749,14 +751,15 @@ static void device_remove_class_symlinks(struct device *dev) sysfs_remove_link(&dev->kobj, "device"); } - if (dev->kobj.parent != &dev->class->p->subsys.kobj && + if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && device_is_not_partition(dev)) - sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->class_subsys.kobj, + dev->bus_id); #else if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); - sysfs_remove_link(&dev->class->p->subsys.kobj, dev->bus_id); + sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id); #endif sysfs_remove_link(&dev->kobj, "subsystem"); @@ -1350,11 +1353,11 @@ int device_rename(struct device *dev, char *new_name) } #else if (dev->class) { - error = sysfs_create_link(&dev->class->p->subsys.kobj, + error = sysfs_create_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev->bus_id); if (error) goto out; - sysfs_remove_link(&dev->class->p->subsys.kobj, + sysfs_remove_link(&dev->class->p->class_subsys.kobj, old_device_name); } #endif -- cgit v1.2.3-70-g09d2 From d9a0157328507c5f563e16a583cd0a063854aebb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 May 2008 09:28:39 -0700 Subject: class: rename "sem" to "class_sem" in internal class structure This renames the struct class "sem" field to be "class_sem" to make things easier when struct bus_type and struct class merge in the future. It also makes grepping for fields easier as well. Based on an idea from Kay. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 4 ++-- drivers/base/class.c | 22 +++++++++++----------- drivers/base/core.c | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/base.h b/drivers/base/base.h index a77d4bd2ea6..4435732437a 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -45,7 +45,7 @@ struct driver_private { * @class_devices - list of devices associated with this class * @class_interfaces - list of class_interfaces associated with this class * @class_dirs - - * @sem - semaphore to protect the children, devices, and interfaces lists. + * @class_sem - semaphore to protect the children, devices, and interfaces lists. * @class - pointer back to the struct class that this structure is associated * with. * @@ -58,7 +58,7 @@ struct class_private { struct list_head class_devices; struct list_head class_interfaces; struct kset class_dirs; - struct semaphore sem; + struct semaphore class_sem; struct class *class; }; #define to_class(obj) \ diff --git a/drivers/base/class.c b/drivers/base/class.c index 86778b86496..d24d21114cc 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -147,7 +147,7 @@ int class_register(struct class *cls) INIT_LIST_HEAD(&cp->class_devices); INIT_LIST_HEAD(&cp->class_interfaces); kset_init(&cp->class_dirs); - init_MUTEX(&cp->sem); + init_MUTEX(&cp->class_sem); error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); if (error) { kfree(cp); @@ -278,7 +278,7 @@ char *make_class_name(const char *name, struct kobject *kobj) * We check the return of @fn each time. If it returns anything * other than 0, we break out and return that value. * - * Note, we hold class->sem in this function, so it can not be + * Note, we hold class->class_sem in this function, so it can not be * re-acquired in @fn, otherwise it will self-deadlocking. For * example, calls to add or remove class members would be verboten. */ @@ -290,7 +290,7 @@ int class_for_each_device(struct class *class, struct device *start, if (!class) return -EINVAL; - down(&class->p->sem); + down(&class->p->class_sem); list_for_each_entry(dev, &class->p->class_devices, node) { if (start) { if (start == dev) @@ -303,7 +303,7 @@ int class_for_each_device(struct class *class, struct device *start, if (error) break; } - up(&class->p->sem); + up(&class->p->class_sem); return error; } @@ -326,7 +326,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device); * * Note, you will need to drop the reference with put_device() after use. * - * We hold class->sem in this function, so it can not be + * We hold class->class_sem in this function, so it can not be * re-acquired in @match, otherwise it will self-deadlocking. For * example, calls to add or remove class members would be verboten. */ @@ -340,7 +340,7 @@ struct device *class_find_device(struct class *class, struct device *start, if (!class) return NULL; - down(&class->p->sem); + down(&class->p->class_sem); list_for_each_entry(dev, &class->p->class_devices, node) { if (start) { if (start == dev) @@ -354,7 +354,7 @@ struct device *class_find_device(struct class *class, struct device *start, } else put_device(dev); } - up(&class->p->sem); + up(&class->p->class_sem); return found ? dev : NULL; } @@ -372,13 +372,13 @@ int class_interface_register(struct class_interface *class_intf) if (!parent) return -EINVAL; - down(&parent->p->sem); + down(&parent->p->class_sem); list_add_tail(&class_intf->node, &parent->p->class_interfaces); if (class_intf->add_dev) { list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->add_dev(dev, class_intf); } - up(&parent->p->sem); + up(&parent->p->class_sem); return 0; } @@ -391,13 +391,13 @@ void class_interface_unregister(struct class_interface *class_intf) if (!parent) return; - down(&parent->p->sem); + down(&parent->p->class_sem); list_del_init(&class_intf->node); if (class_intf->remove_dev) { list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->remove_dev(dev, class_intf); } - up(&parent->p->sem); + up(&parent->p->class_sem); class_put(parent); } diff --git a/drivers/base/core.c b/drivers/base/core.c index 6e1cff296d9..b90ae6f7be8 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -907,7 +907,7 @@ int device_add(struct device *dev) klist_add_tail(&dev->knode_parent, &parent->klist_children); if (dev->class) { - down(&dev->class->p->sem); + down(&dev->class->p->class_sem); /* tie the class to the device */ list_add_tail(&dev->node, &dev->class->p->class_devices); @@ -916,7 +916,7 @@ int device_add(struct device *dev) &dev->class->p->class_interfaces, node) if (class_intf->add_dev) class_intf->add_dev(dev, class_intf); - up(&dev->class->p->sem); + up(&dev->class->p->class_sem); } Done: put_device(dev); @@ -1017,7 +1017,7 @@ void device_del(struct device *dev) if (dev->class) { device_remove_class_symlinks(dev); - down(&dev->class->p->sem); + down(&dev->class->p->class_sem); /* notify any interfaces that the device is now gone */ list_for_each_entry(class_intf, &dev->class->p->class_interfaces, node) @@ -1025,7 +1025,7 @@ void device_del(struct device *dev) class_intf->remove_dev(dev, class_intf); /* remove the device from the class list */ list_del_init(&dev->node); - up(&dev->class->p->sem); + up(&dev->class->p->class_sem); } device_remove_file(dev, &uevent_attr); device_remove_attrs(dev); -- cgit v1.2.3-70-g09d2 From f75b1c60fc1e53c4004a79ea0be071aa3318cdcc Mon Sep 17 00:00:00 2001 From: Dave Young Date: Wed, 28 May 2008 09:28:39 -0700 Subject: class: change internal semaphore to a mutex Now that the lockdep infrastructure in the class core is in place, we should be able to properly change the internal class semaphore to be a mutex. David wrote the original patch, and Greg fixed it up to apply properly due to all of the recent changes in this area. From: Dave Young Cc: Matthew Wilcox Cc: Kay Sievers Cc: Andrew Morton Cc: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 4 ++-- drivers/base/class.c | 23 ++++++++++++----------- drivers/base/core.c | 9 +++++---- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/base.h b/drivers/base/base.h index c035dc23266..31dc0cd84af 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -44,7 +44,7 @@ struct driver_private { * @class_devices - list of devices associated with this class * @class_interfaces - list of class_interfaces associated with this class * @class_dirs - "glue" directory for virtual devices associated with this class - * @class_sem - semaphore to protect the children, devices, and interfaces lists. + * @class_mutex - mutex to protect the children, devices, and interfaces lists. * @class - pointer back to the struct class that this structure is associated * with. * @@ -57,7 +57,7 @@ struct class_private { struct list_head class_devices; struct list_head class_interfaces; struct kset class_dirs; - struct semaphore class_sem; + struct mutex class_mutex; struct class *class; }; #define to_class(obj) \ diff --git a/drivers/base/class.c b/drivers/base/class.c index 89000566690..839d27cecb3 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "base.h" #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) @@ -147,7 +148,7 @@ int __class_register(struct class *cls, struct lock_class_key *key) INIT_LIST_HEAD(&cp->class_devices); INIT_LIST_HEAD(&cp->class_interfaces); kset_init(&cp->class_dirs); - init_MUTEX(&cp->class_sem); + __mutex_init(&cp->class_mutex, "struct class mutex", key); error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); if (error) { kfree(cp); @@ -281,7 +282,7 @@ char *make_class_name(const char *name, struct kobject *kobj) * We check the return of @fn each time. If it returns anything * other than 0, we break out and return that value. * - * Note, we hold class->class_sem in this function, so it can not be + * Note, we hold class->class_mutex in this function, so it can not be * re-acquired in @fn, otherwise it will self-deadlocking. For * example, calls to add or remove class members would be verboten. */ @@ -293,7 +294,7 @@ int class_for_each_device(struct class *class, struct device *start, if (!class) return -EINVAL; - down(&class->p->class_sem); + mutex_lock(&class->p->class_mutex); list_for_each_entry(dev, &class->p->class_devices, node) { if (start) { if (start == dev) @@ -306,7 +307,7 @@ int class_for_each_device(struct class *class, struct device *start, if (error) break; } - up(&class->p->class_sem); + mutex_unlock(&class->p->class_mutex); return error; } @@ -329,7 +330,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device); * * Note, you will need to drop the reference with put_device() after use. * - * We hold class->class_sem in this function, so it can not be + * We hold class->class_mutex in this function, so it can not be * re-acquired in @match, otherwise it will self-deadlocking. For * example, calls to add or remove class members would be verboten. */ @@ -343,7 +344,7 @@ struct device *class_find_device(struct class *class, struct device *start, if (!class) return NULL; - down(&class->p->class_sem); + mutex_lock(&class->p->class_mutex); list_for_each_entry(dev, &class->p->class_devices, node) { if (start) { if (start == dev) @@ -357,7 +358,7 @@ struct device *class_find_device(struct class *class, struct device *start, } else put_device(dev); } - up(&class->p->class_sem); + mutex_unlock(&class->p->class_mutex); return found ? dev : NULL; } @@ -375,13 +376,13 @@ int class_interface_register(struct class_interface *class_intf) if (!parent) return -EINVAL; - down(&parent->p->class_sem); + mutex_lock(&parent->p->class_mutex); list_add_tail(&class_intf->node, &parent->p->class_interfaces); if (class_intf->add_dev) { list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->add_dev(dev, class_intf); } - up(&parent->p->class_sem); + mutex_unlock(&parent->p->class_mutex); return 0; } @@ -394,13 +395,13 @@ void class_interface_unregister(struct class_interface *class_intf) if (!parent) return; - down(&parent->p->class_sem); + mutex_lock(&parent->p->class_mutex); list_del_init(&class_intf->node); if (class_intf->remove_dev) { list_for_each_entry(dev, &parent->p->class_devices, node) class_intf->remove_dev(dev, class_intf); } - up(&parent->p->class_sem); + mutex_unlock(&parent->p->class_mutex); class_put(parent); } diff --git a/drivers/base/core.c b/drivers/base/core.c index b90ae6f7be8..c05b1159023 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -907,7 +908,7 @@ int device_add(struct device *dev) klist_add_tail(&dev->knode_parent, &parent->klist_children); if (dev->class) { - down(&dev->class->p->class_sem); + mutex_lock(&dev->class->p->class_mutex); /* tie the class to the device */ list_add_tail(&dev->node, &dev->class->p->class_devices); @@ -916,7 +917,7 @@ int device_add(struct device *dev) &dev->class->p->class_interfaces, node) if (class_intf->add_dev) class_intf->add_dev(dev, class_intf); - up(&dev->class->p->class_sem); + mutex_unlock(&dev->class->p->class_mutex); } Done: put_device(dev); @@ -1017,7 +1018,7 @@ void device_del(struct device *dev) if (dev->class) { device_remove_class_symlinks(dev); - down(&dev->class->p->class_sem); + mutex_lock(&dev->class->p->class_mutex); /* notify any interfaces that the device is now gone */ list_for_each_entry(class_intf, &dev->class->p->class_interfaces, node) @@ -1025,7 +1026,7 @@ void device_del(struct device *dev) class_intf->remove_dev(dev, class_intf); /* remove the device from the class list */ list_del_init(&dev->node); - up(&dev->class->p->class_sem); + mutex_unlock(&dev->class->p->class_mutex); } device_remove_file(dev, &uevent_attr); device_remove_attrs(dev); -- cgit v1.2.3-70-g09d2 From 36ce6dad6e3cb3f050ed41e0beac0070d2062b25 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 10 Jun 2008 11:09:08 +0200 Subject: driver core: Suppress sysfs warnings for device_rename(). driver core: Suppress sysfs warnings for device_rename(). Renaming network devices to an already existing name is not something we want sysfs to print a scary warning for, since the callers can deal with this correctly. So let's introduce sysfs_create_link_nowarn() which gets rid of the common warning. Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 9 +++++---- fs/sysfs/dir.c | 37 +++++++++++++++++++++++++++++++++++-- fs/sysfs/symlink.c | 41 +++++++++++++++++++++++++++++++++-------- fs/sysfs/sysfs.h | 1 + include/linux/sysfs.h | 10 ++++++++++ 5 files changed, 84 insertions(+), 14 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/core.c b/drivers/base/core.c index c05b1159023..7d5c63c81a5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1345,8 +1345,9 @@ int device_rename(struct device *dev, char *new_name) if (old_class_name) { new_class_name = make_class_name(dev->class->name, &dev->kobj); if (new_class_name) { - error = sysfs_create_link(&dev->parent->kobj, - &dev->kobj, new_class_name); + error = sysfs_create_link_nowarn(&dev->parent->kobj, + &dev->kobj, + new_class_name); if (error) goto out; sysfs_remove_link(&dev->parent->kobj, old_class_name); @@ -1354,8 +1355,8 @@ int device_rename(struct device *dev, char *new_name) } #else if (dev->class) { - error = sysfs_create_link(&dev->class->p->class_subsys.kobj, - &dev->kobj, dev->bus_id); + error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj, + &dev->kobj, dev->bus_id); if (error) goto out; sysfs_remove_link(&dev->class->p->class_subsys.kobj, diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 8c0e4b92574..c1a7efb310b 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -398,7 +398,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, } /** - * sysfs_add_one - add sysfs_dirent to parent + * __sysfs_add_one - add sysfs_dirent to parent without warning * @acxt: addrm context to use * @sd: sysfs_dirent to be added * @@ -417,7 +417,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, * 0 on success, -EEXIST if entry with the given name already * exists. */ -int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) +int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) { if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) return -EEXIST; @@ -434,6 +434,39 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) return 0; } +/** + * sysfs_add_one - add sysfs_dirent to parent + * @acxt: addrm context to use + * @sd: sysfs_dirent to be added + * + * Get @acxt->parent_sd and set sd->s_parent to it and increment + * nlink of parent inode if @sd is a directory and link into the + * children list of the parent. + * + * This function should be called between calls to + * sysfs_addrm_start() and sysfs_addrm_finish() and should be + * passed the same @acxt as passed to sysfs_addrm_start(). + * + * LOCKING: + * Determined by sysfs_addrm_start(). + * + * RETURNS: + * 0 on success, -EEXIST if entry with the given name already + * exists. + */ +int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) +{ + int ret; + + ret = __sysfs_add_one(acxt, sd); + if (ret == -EEXIST) { + printk(KERN_WARNING "sysfs: duplicate filename '%s' " + "can not be created\n", sd->s_name); + WARN_ON(1); + } + return ret; +} + /** * sysfs_remove_one - remove sysfs_dirent from parent * @acxt: addrm context to use diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 817f5966edc..a3ba217fbe7 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -19,13 +19,8 @@ #include "sysfs.h" -/** - * sysfs_create_link - create symlink between two objects. - * @kobj: object whose directory we're creating the link in. - * @target: object we're pointing to. - * @name: name of the symlink. - */ -int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) +static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, + const char *name, int warn) { struct sysfs_dirent *parent_sd = NULL; struct sysfs_dirent *target_sd = NULL; @@ -65,7 +60,10 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char target_sd = NULL; /* reference is now owned by the symlink */ sysfs_addrm_start(&acxt, parent_sd); - error = sysfs_add_one(&acxt, sd); + if (warn) + error = sysfs_add_one(&acxt, sd); + else + error = __sysfs_add_one(&acxt, sd); sysfs_addrm_finish(&acxt); if (error) @@ -79,6 +77,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char return error; } +/** + * sysfs_create_link - create symlink between two objects. + * @kobj: object whose directory we're creating the link in. + * @target: object we're pointing to. + * @name: name of the symlink. + */ +int sysfs_create_link(struct kobject *kobj, struct kobject *target, + const char *name) +{ + return sysfs_do_create_link(kobj, target, name, 1); +} + +/** + * sysfs_create_link_nowarn - create symlink between two objects. + * @kobj: object whose directory we're creating the link in. + * @target: object we're pointing to. + * @name: name of the symlink. + * + * This function does the same as sysf_create_link(), but it + * doesn't warn if the link already exists. + */ +int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, + const char *name) +{ + return sysfs_do_create_link(kobj, target, name, 0); +} + /** * sysfs_remove_link - remove symlink in object's directory. * @kobj: object we're acting for. diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index ce4e15f8aae..a5db496f71c 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -107,6 +107,7 @@ struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd); void sysfs_put_active_two(struct sysfs_dirent *sd); void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *parent_sd); +int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 7858eac40aa..37fa24152bd 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -101,6 +101,9 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr); int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name); +int __must_check sysfs_create_link_nowarn(struct kobject *kobj, + struct kobject *target, + const char *name); void sysfs_remove_link(struct kobject *kobj, const char *name); int __must_check sysfs_create_group(struct kobject *kobj, @@ -180,6 +183,13 @@ static inline int sysfs_create_link(struct kobject *kobj, return 0; } +static inline int sysfs_create_link_nowarn(struct kobject *kobj, + struct kobject *target, + const char *name) +{ + return 0; +} + static inline void sysfs_remove_link(struct kobject *kobj, const char *name) { } -- cgit v1.2.3-70-g09d2 From f810a5cf28a818db96333cd23646f0227ec015b4 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:39 -0700 Subject: Use WARN() in drivers/base/ Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Signed-off-by: Arjan van de Ven Cc: Greg KH Cc: Kay Sievers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/core.c | 6 ++---- drivers/base/memory.c | 3 +-- drivers/base/sys.c | 12 ++++-------- 3 files changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers/base/core.c') diff --git a/drivers/base/core.c b/drivers/base/core.c index 7d5c63c81a5..068aa1c9538 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -116,12 +116,10 @@ static void device_release(struct kobject *kobj) dev->type->release(dev); else if (dev->class && dev->class->dev_release) dev->class->dev_release(dev); - else { - printk(KERN_ERR "Device '%s' does not have a release() " + else + WARN(1, KERN_ERR "Device '%s' does not have a release() " "function, it is broken and must be fixed.\n", dev->bus_id); - WARN_ON(1); - } } static struct kobj_type device_ktype = { diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 855ed1a9f97..3ad49a00029 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -204,9 +204,8 @@ memory_block_action(struct memory_block *mem, unsigned long action) } break; default: - printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", + WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", __func__, mem, action, action); - WARN_ON(1); ret = -EINVAL; } diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 40fc14f0354..75dd6e22faf 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -168,19 +168,16 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) int err = 0; if (!cls) { - printk(KERN_WARNING "sysdev: invalid class passed to " + WARN(1, KERN_WARNING "sysdev: invalid class passed to " "sysdev_driver_register!\n"); - WARN_ON(1); return -EINVAL; } /* Check whether this driver has already been added to a class. */ - if (drv->entry.next && !list_empty(&drv->entry)) { - printk(KERN_WARNING "sysdev: class %s: driver (%p) has already" + if (drv->entry.next && !list_empty(&drv->entry)) + WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" " been registered to a class, something is wrong, but " "will forge on!\n", cls->name, drv); - WARN_ON(1); - } mutex_lock(&sysdev_drivers_lock); if (cls && kset_get(&cls->kset)) { @@ -194,8 +191,7 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) } } else { err = -EINVAL; - printk(KERN_ERR "%s: invalid device class\n", __func__); - WARN_ON(1); + WARN(1, KERN_ERR "%s: invalid device class\n", __func__); } mutex_unlock(&sysdev_drivers_lock); return err; -- cgit v1.2.3-70-g09d2