From 8d790d74085833ba2a3e84b5bcd683be4981c29a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 26 Apr 2005 02:34:05 -0500 Subject: [PATCH] make driver's name be const char * Driver core: change driver's, bus's, class's and platform device's names to be const char * so one can use const char *drv_name = "asdfg"; when initializing structures. Also kill couple of whitespaces. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index df94c0d..fa9e6ca 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -47,7 +47,7 @@ struct class_device; struct class_simple; struct bus_type { - char * name; + const char * name; struct subsystem subsys; struct kset drivers; @@ -98,17 +98,17 @@ extern int bus_create_file(struct bus_type *, struct bus_attribute *); extern void bus_remove_file(struct bus_type *, struct bus_attribute *); struct device_driver { - char * name; + const char * name; struct bus_type * bus; struct completion unloaded; struct kobject kobj; struct list_head devices; - struct module * owner; + struct module * owner; int (*probe) (struct device * dev); - int (*remove) (struct device * dev); + int (*remove) (struct device * dev); void (*shutdown) (struct device * dev); int (*suspend) (struct device * dev, pm_message_t state, u32 level); int (*resume) (struct device * dev, u32 level); @@ -142,7 +142,7 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute * * device classes */ struct class { - char * name; + const char * name; struct subsystem subsys; struct list_head children; @@ -366,7 +366,7 @@ extern struct device *device_find(const char *name, struct bus_type *bus); /* drivers/base/platform.c */ struct platform_device { - char * name; + const char * name; u32 id; struct device dev; u32 num_resources; -- cgit v1.1 From e9ba6365fd4f0d9e7d022c883bd044fbaa48257f Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Tue, 15 Mar 2005 11:54:21 -0800 Subject: [PATCH] CLASS: move a "simple" class logic into the class core. One step on improving the class api so that it can not be used incorrectly. This also fixes the module owner issue with the dev files that happened when the devt logic moved to the class core. Based on a patch originally written by Kay Sievers Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index fa9e6ca..73250d0 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -143,6 +143,7 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute * */ struct class { const char * name; + struct module * owner; struct subsystem subsys; struct list_head children; @@ -185,6 +186,7 @@ struct class_device { struct kobject kobj; struct class * class; /* required */ dev_t devt; /* dev_t, creates the sysfs "dev" */ + struct class_device_attribute *devt_attr; struct device * dev; /* not necessary, but nice to have */ void * class_data; /* class-specific data */ @@ -245,6 +247,13 @@ struct class_interface { extern int class_interface_register(struct class_interface *); extern void class_interface_unregister(struct class_interface *); +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 void class_device_destroy(struct class *cls, dev_t devt); + /* interface for class simple stuff */ extern struct class_simple *class_simple_create(struct module *owner, char *name); extern void class_simple_destroy(struct class_simple *cs); -- cgit v1.1 From cd987d38cc59053e0bab8150ffaca33b109067f3 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Wed, 23 Mar 2005 11:12:38 -0800 Subject: [PATCH] class: remove class_simple code, as no one in the tree is using it anymore. Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 73250d0..68a9535 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -44,7 +44,6 @@ struct device; struct device_driver; struct class; struct class_device; -struct class_simple; struct bus_type { const char * name; @@ -254,15 +253,6 @@ extern struct class_device *class_device_create(struct class *cls, dev_t devt, __attribute__((format(printf,4,5))); extern void class_device_destroy(struct class *cls, dev_t devt); -/* interface for class simple stuff */ -extern struct class_simple *class_simple_create(struct module *owner, char *name); -extern void class_simple_destroy(struct class_simple *cs); -extern struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...) - __attribute__((format(printf,4,5))); -extern int class_simple_set_hotplug(struct class_simple *, - int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size)); -extern void class_simple_device_remove(dev_t dev); - struct device { struct list_head node; /* node in sibling list */ -- cgit v1.1 From af70316af182f4716cc5eec7e0d27fc731d164bd Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Mon, 21 Mar 2005 10:41:04 -0800 Subject: [PATCH] Add a semaphore to struct device to synchronize calls to its driver. This adds a per-device semaphore that is taken before every call from the core to a driver method. This prevents e.g. simultaneous calls to the ->suspend() or ->resume() and ->probe() or ->release(), potentially saving a whole lot of headaches. It also moves us a step closer to removing the bus rwsem, since it protects the fields in struct device that are modified by the core. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 68a9535..195b327 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -264,6 +264,10 @@ struct device { struct kobject kobj; char bus_id[BUS_ID_SIZE]; /* position on parent bus */ + struct semaphore sem; /* semaphore to synchronize calls to + * its driver. + */ + struct bus_type * bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ -- cgit v1.1 From fae3cd00255e3e51ffd59fedb1bdb91ec96be395 Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Mon, 21 Mar 2005 10:59:56 -0800 Subject: [PATCH] Add driver_for_each_device(). Now there's an iterator for accessing each device bound to a driver. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman Index: linux-2.6.12-rc2/drivers/base/driver.c =================================================================== --- include/linux/device.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 195b327..10f5aa2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -136,6 +136,9 @@ struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store) extern int driver_create_file(struct device_driver *, struct driver_attribute *); extern void driver_remove_file(struct device_driver *, struct driver_attribute *); +extern int driver_for_each_device(struct device_driver * drv, struct device * start, + void * data, int (*fn)(struct device *, void *)); + /* * device classes -- cgit v1.1 From 465c7a3a3a5aabcedd2e43612cac5a12f23da19a Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Mon, 21 Mar 2005 11:49:14 -0800 Subject: [PATCH] Add a klist to struct bus_type for its devices. - Use it for bus_for_each_dev(). - Use the klist spinlock instead of the bus rwsem. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 10f5aa2..e36953c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ struct bus_type { struct subsystem subsys; struct kset drivers; struct kset devices; + struct klist klist_devices; struct bus_attribute * bus_attrs; struct device_attribute * dev_attrs; @@ -262,6 +264,7 @@ struct device { struct list_head bus_list; /* node in bus's list */ struct list_head driver_list; struct list_head children; + struct klist_node knode_bus; struct device * parent; struct kobject kobj; -- cgit v1.1 From 38fdac3cdce276554b4484a41f8ec2daf81cb2ff Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Mon, 21 Mar 2005 12:00:18 -0800 Subject: [PATCH] Add a klist to struct bus_type for its drivers. - Use it in bus_for_each_drv(). - Use the klist spinlock instead of the bus rwsem. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index e36953c..ea9ab33 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -53,6 +53,7 @@ struct bus_type { struct kset drivers; struct kset devices; struct klist klist_devices; + struct klist klist_drivers; struct bus_attribute * bus_attrs; struct device_attribute * dev_attrs; @@ -105,6 +106,7 @@ struct device_driver { struct completion unloaded; struct kobject kobj; struct list_head devices; + struct klist_node knode_bus; struct module * owner; -- cgit v1.1 From 94e7b1c5ff2055571703e38b059afffe17658432 Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Mon, 21 Mar 2005 12:25:36 -0800 Subject: [PATCH] Add a klist to struct device_driver for the devices bound to it. - Use it in driver_for_each_device() instead of the regular list_head and stop using the bus's rwsem for protection. - Use driver_for_each_device() in driver_detach() so we don't deadlock on the bus's rwsem. - Remove ->devices. - Move klist access and sysfs link access out from under device's semaphore, since they're synchronized through other means. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index ea9ab33..96c71b5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -105,7 +105,7 @@ struct device_driver { struct completion unloaded; struct kobject kobj; - struct list_head devices; + struct klist klist_devices; struct klist_node knode_bus; struct module * owner; @@ -266,6 +266,7 @@ struct device { struct list_head bus_list; /* node in bus's list */ struct list_head driver_list; struct list_head children; + struct klist_node knode_driver; struct klist_node knode_bus; struct device * parent; -- cgit v1.1 From cb85b6f1cc811ecb9ed4b950206d8941ba710e68 Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Thu, 24 Mar 2005 10:48:35 -0800 Subject: [PATCH] Remove the unused device_find(). Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 96c71b5..f1c38d8 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -372,7 +372,6 @@ extern int (*platform_notify_remove)(struct device * dev); */ extern struct device * get_device(struct device * dev); extern void put_device(struct device * dev); -extern struct device *device_find(const char *name, struct bus_type *bus); /* drivers/base/platform.c */ -- cgit v1.1 From 7dc35cdf69149a7f2b5216ada9bafe359746ac1c Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Thu, 24 Mar 2005 13:03:35 -0800 Subject: [PATCH] Remove struct device::bus_list. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index f1c38d8..13f6585 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -263,7 +263,6 @@ extern void class_device_destroy(struct class *cls, dev_t devt); struct device { struct list_head node; /* node in sibling list */ - struct list_head bus_list; /* node in bus's list */ struct list_head driver_list; struct list_head children; struct klist_node knode_driver; -- cgit v1.1 From 63c4f204ffc8219696bda88eb20c9873d007a2fc Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Thu, 24 Mar 2005 13:08:05 -0800 Subject: [PATCH] Remove struct device::driver_list. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 13f6585..d243493 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -263,7 +263,6 @@ extern void class_device_destroy(struct class *cls, dev_t devt); struct device { struct list_head node; /* node in sibling list */ - struct list_head driver_list; struct list_head children; struct klist_node knode_driver; struct klist_node knode_bus; -- cgit v1.1 From 36239577cfb6b9a7c111209536b54200b0252ebf Mon Sep 17 00:00:00 2001 From: "mochel@digitalimplant.org" Date: Thu, 24 Mar 2005 19:08:30 -0800 Subject: [PATCH] Use a klist for device child lists. - Use klist iterator in device_for_each_child(), making it safe to use for removing devices. - Remove unused list_to_dev() function. - Kills all usage of devices_subsys.rwsem. Signed-off-by: Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index d243493..4324926 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -262,8 +262,8 @@ extern void class_device_destroy(struct class *cls, dev_t devt); struct device { - struct list_head node; /* node in sibling list */ - struct list_head children; + struct klist klist_children; + struct klist_node knode_parent; /* node in sibling list */ struct klist_node knode_driver; struct klist_node knode_bus; struct device * parent; @@ -298,12 +298,6 @@ struct device { void (*release)(struct device * dev); }; -static inline struct device * -list_to_dev(struct list_head *node) -{ - return list_entry(node, struct device, node); -} - static inline void * dev_get_drvdata (struct device *dev) { -- cgit v1.1 From 0d3e5a2e39b6ba2974e9e7c2a429018c45de8e76 Mon Sep 17 00:00:00 2001 From: Patrick Mochel Date: Tue, 5 Apr 2005 23:46:33 -0700 Subject: [PATCH] Driver Core: fix bk-driver-core kills ppc64 There's no check to see if the device is already bound to a driver, which could do bad things. The first thing to go wrong is that it will try to match a driver with a device already bound to one. In some cases (it appears with USB with drivers/usb/core/usb.c::usb_match_id()), some drivers will match a device based on the class type, so it would be common (especially for HID devices) to match a device that is already bound. The fun comes when ->probe() is called, it fails, then driver_probe_device() does this: dev->driver = NULL; Later on, that pointer could be be dereferenced without checking and cause hell to break loose. This problem could be nasty. It's very hardware dependent, since some devices could have a different set of matching qualifiers than others. Now, I don't quite see exactly where/how you were getting that crash. You're dereferencing bad memory, but I'm not sure which pointer was bad and where it came from, but it could have come from a couple of different places. The patch below will hopefully fix it all up for you. It's against 2.6.12-rc2-mm1, and does the following: - Move logic to driver_probe_device() and comments uncommon returns: 1 - If device is bound 0 - If device not bound, and no error error - If there was an error. - Move locking to caller of that function, since we want to lock a device for the entire time we're trying to bind it to a driver (to prevent against a driver being loaded at the same time). - Update __device_attach() and __driver_attach() to do that locking. - Check if device is already bound in __driver_attach() - Update the converse device_release_driver() so it locks the device around all of the operations. - Mark driver_probe_device() as static and remove export. It's an internal function, it should stay that way, and there are no other callers. If there is ever a need to export it, we can audit it as necessary. Signed-off-by: Andrew Morton --- include/linux/device.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 4324926..91aac34 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -325,7 +325,6 @@ extern int device_for_each_child(struct device *, void *, * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ -extern int driver_probe_device(struct device_driver * drv, struct device * dev); extern void device_bind_driver(struct device * dev); extern void device_release_driver(struct device * dev); extern int device_attach(struct device * dev); -- cgit v1.1 From 54b6f35c99974e99e64c05c2895718355123c55f Mon Sep 17 00:00:00 2001 From: Yani Ioannou Date: Tue, 17 May 2005 06:39:34 -0400 Subject: [PATCH] Driver core: change device_attribute callbacks This patch adds the device_attribute paramerter to the device_attribute store and show sysfs callback functions, and passes a reference to the attribute when the callbacks are called. Signed-off-by: Yani Ioannou Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux/device.h') diff --git a/include/linux/device.h b/include/linux/device.h index 91aac34..7b781a7 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -335,8 +335,10 @@ extern void driver_attach(struct device_driver * drv); struct device_attribute { struct attribute attr; - ssize_t (*show)(struct device * dev, char * buf); - ssize_t (*store)(struct device * dev, const char * buf, size_t count); + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); }; #define DEVICE_ATTR(_name,_mode,_show,_store) \ -- cgit v1.1