From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Greg KH <greg@kroah.com>
Cc: linux-kernel@vger.kernel.org, Tejun Heo <tj@home-tj.org>,
Patrick Mochel <mochel@digitalimplant.org>,
Adam Belay <ambx1@neo.rr.com>
Subject: Re: [RFC] [PATCH] driver core: allow userspace to unbind drivers from devices.
Date: Tue, 16 Nov 2004 15:43:21 -0500 [thread overview]
Message-ID: <d120d50004111612437ebe76d9@mail.gmail.com> (raw)
In-Reply-To: <20041116055440.GH29328@kroah.com>
[-- Attachment #1: Type: text/plain, Size: 606 bytes --]
On Mon, 15 Nov 2004 21:54:40 -0800, Greg KH <greg@kroah.com> wrote:
> On Tue, Nov 09, 2004 at 10:49:43PM -0500, Dmitry Torokhov wrote:
> > In the meantime, can I please have bind_mode patch applied? I believe
> > it is useful regardless of which bind/unbind solution will be adopted
> > and having them will allow me clean up serio bus implementaion quite a
> > bit.
> >
> > Pretty please...
>
> Care to resend it? I can't find it in my archives.
>
Here it is, against 2.6.10-rc2. Apologies for sending it as an attachment
but this interface will not let me put it inline without mangling.
--
Dmitry
[-- Attachment #2: bind_mode-attr.patch --]
[-- Type: application/octet-stream, Size: 10551 bytes --]
===================================================================
ChangeSet@1.1963, 2004-11-16 02:07:15-05:00, dtor_core@ameritech.net
Driver core: add "bind_mode" default device and driver attribute.
Calls to device_attach() and driver_attach() will not
bind device and driver if either one of them is in
"manual" bind mode. Manual binding is expected to be
handled by bus's drvctl()
echo -n "manual" > /sus/bus/serio/devices/serio2/bind_mode
echo -n "auto" > /sys/bus/serio/drivers/serio_raw/bind_mode
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/base/bus.c | 20 +++++++----
drivers/base/interface.c | 70 +++++++++++++++++++++++++++++++++++++---
drivers/input/serio/serio.c | 58 ++-------------------------------
drivers/input/serio/serio_raw.c | 4 +-
include/linux/device.h | 5 ++
include/linux/serio.h | 4 --
6 files changed, 89 insertions(+), 72 deletions(-)
===================================================================
diff -urN a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c 2004-11-16 02:20:53 -0500
+++ b/drivers/base/bus.c 2004-11-16 02:20:53 -0500
@@ -68,9 +68,12 @@
up(&drv->unload_sem);
}
+extern struct attribute * drv_default_attrs[];
+
static struct kobj_type ktype_driver = {
.sysfs_ops = &driver_sysfs_ops,
.release = driver_release,
+ .default_attrs = drv_default_attrs,
};
@@ -319,9 +322,12 @@
return 1;
}
- if (bus->match) {
- list_for_each(entry, &bus->drivers.list) {
- struct device_driver * drv = to_drv(entry);
+ if (dev->manual_bind || !bus->match)
+ return 0;
+
+ list_for_each(entry, &bus->drivers.list) {
+ struct device_driver * drv = to_drv(entry);
+ if (!drv->manual_bind) {
error = driver_probe_device(drv, dev);
if (!error)
/* success, driver matched */
@@ -329,8 +335,8 @@
if (error != -ENODEV)
/* driver matched but the probe failed */
printk(KERN_WARNING
- "%s: probe of %s failed with error %d\n",
- drv->name, dev->bus_id, error);
+ "%s: probe of %s failed with error %d\n",
+ drv->name, dev->bus_id, error);
}
}
@@ -356,12 +362,12 @@
struct list_head * entry;
int error;
- if (!bus->match)
+ if (drv->manual_bind || !bus->match)
return;
list_for_each(entry, &bus->devices.list) {
struct device * dev = container_of(entry, struct device, bus_list);
- if (!dev->driver) {
+ if (!dev->driver && !dev->manual_bind) {
error = driver_probe_device(drv, dev);
if (error && (error != -ENODEV))
/* driver matched but the probe failed */
diff -urN a/drivers/base/interface.c b/drivers/base/interface.c
--- a/drivers/base/interface.c 2004-11-16 02:20:53 -0500
+++ b/drivers/base/interface.c 2004-11-16 02:20:53 -0500
@@ -1,6 +1,6 @@
/*
* drivers/base/interface.c - common driverfs interface that's exported to
- * the world for all devices.
+ * the world for all devices and drivers.
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
@@ -14,6 +14,40 @@
#include <linux/stat.h>
#include <linux/string.h>
+
+static int parse_bind_mode(const char * buf, size_t count, unsigned int * manual_bind)
+{
+ int retval = count;
+
+ if (!strncmp(buf, "manual", count)) {
+ *manual_bind = 1;
+ } else if (!strncmp(buf, "auto", count)) {
+ *manual_bind = 0;
+ } else {
+ retval = -EINVAL;
+ }
+ return retval;
+}
+
+/**
+ * bind_mode - controls the binding mode for the device.
+ *
+ * When set to "auto" driver core will try to automatically bind the
+ * device once appropriate driver becomes available. When bind mode
+ * is "manual" user intervention is required.
+ */
+
+static ssize_t dev_bind_mode_show(struct device * dev, char * buf)
+{
+ return sprintf(buf, "%s\n", dev->manual_bind ? "manual" : "auto");
+}
+
+static ssize_t dev_bind_mode_store(struct device * dev, const char * buf, size_t count)
+{
+ return parse_bind_mode(buf, count, &dev->manual_bind);
+}
+
+
/**
* detach_state - control the default power state for the device.
*
@@ -27,12 +61,12 @@
* driver's suspend method.
*/
-static ssize_t detach_show(struct device * dev, char * buf)
+static ssize_t dev_detach_show(struct device * dev, char * buf)
{
return sprintf(buf, "%u\n", dev->detach_state);
}
-static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
+static ssize_t dev_detach_store(struct device * dev, const char * buf, size_t n)
{
u32 state;
state = simple_strtoul(buf, NULL, 10);
@@ -42,10 +76,36 @@
return n;
}
-static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
-
+static DEVICE_ATTR(bind_mode, 0644, dev_bind_mode_show, dev_bind_mode_store);
+static DEVICE_ATTR(detach_state, 0644, dev_detach_show, dev_detach_store);
struct attribute * dev_default_attrs[] = {
+ &dev_attr_bind_mode.attr,
&dev_attr_detach_state.attr,
NULL,
};
+
+/**
+ * bind_mode - controls the binding mode for the driver.
+ *
+ * When set to "auto" driver core will try to automatically bind the
+ * driver once appropriate device becomes available. When bind mode
+ * is "manual" user intervention is required.
+ */
+
+static ssize_t drv_bind_mode_show(struct device_driver * drv, char * buf)
+{
+ return sprintf(buf, "%s\n", drv->manual_bind ? "manual" : "auto");
+}
+
+static ssize_t drv_bind_mode_store(struct device_driver * drv, const char * buf, size_t count)
+{
+ return parse_bind_mode(buf, count, &drv->manual_bind);
+}
+
+static DRIVER_ATTR(bind_mode, 0644, drv_bind_mode_show, drv_bind_mode_store);
+
+struct attribute * drv_default_attrs[] = {
+ &driver_attr_bind_mode.attr,
+ NULL,
+};
diff -urN a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c 2004-11-16 02:20:53 -0500
+++ b/drivers/input/serio/serio.c 2004-11-16 02:20:53 -0500
@@ -92,7 +92,7 @@
struct serio_driver *drv;
list_for_each_entry(drv, &serio_driver_list, node)
- if (!drv->manual_bind)
+ if (!drv->driver.manual_bind)
if (serio_bind_driver(serio, drv))
break;
}
@@ -277,33 +277,9 @@
return retval;
}
-static ssize_t serio_show_bind_mode(struct device *dev, char *buf)
-{
- struct serio *serio = to_serio_port(dev);
- return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto");
-}
-
-static ssize_t serio_set_bind_mode(struct device *dev, const char *buf, size_t count)
-{
- struct serio *serio = to_serio_port(dev);
- int retval;
-
- retval = count;
- if (!strncmp(buf, "manual", count)) {
- serio->manual_bind = 1;
- } else if (!strncmp(buf, "auto", count)) {
- serio->manual_bind = 0;
- } else {
- retval = -EINVAL;
- }
-
- return retval;
-}
-
static struct device_attribute serio_device_attrs[] = {
__ATTR(description, S_IRUGO, serio_show_description, NULL),
__ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
- __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
__ATTR_NULL
};
@@ -371,7 +347,7 @@
if (drv)
serio_bind_driver(serio, drv);
- else if (!serio->manual_bind)
+ else if (!serio->dev.manual_bind)
serio_find_driver(serio);
/* Ok, now bind children, if any */
@@ -383,7 +359,7 @@
serio_create_port(serio);
- if (!serio->manual_bind) {
+ if (!serio->dev.manual_bind) {
/*
* With children we just _prefer_ passed in driver,
* but we will try other options in case preferred
@@ -505,34 +481,8 @@
return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
}
-static ssize_t serio_driver_show_bind_mode(struct device_driver *drv, char *buf)
-{
- struct serio_driver *serio_drv = to_serio_driver(drv);
- return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto");
-}
-
-static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char *buf, size_t count)
-{
- struct serio_driver *serio_drv = to_serio_driver(drv);
- int retval;
-
- retval = count;
- if (!strncmp(buf, "manual", count)) {
- serio_drv->manual_bind = 1;
- } else if (!strncmp(buf, "auto", count)) {
- serio_drv->manual_bind = 0;
- } else {
- retval = -EINVAL;
- }
-
- return retval;
-}
-
-
static struct driver_attribute serio_driver_attrs[] = {
__ATTR(description, S_IRUGO, serio_driver_show_description, NULL),
- __ATTR(bind_mode, S_IWUSR | S_IRUGO,
- serio_driver_show_bind_mode, serio_driver_set_bind_mode),
__ATTR_NULL
};
@@ -547,7 +497,7 @@
drv->driver.bus = &serio_bus;
driver_register(&drv->driver);
- if (drv->manual_bind)
+ if (drv->driver.manual_bind)
goto out;
start_over:
diff -urN a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
--- a/drivers/input/serio/serio_raw.c 2004-11-16 02:20:53 -0500
+++ b/drivers/input/serio/serio_raw.c 2004-11-16 02:20:53 -0500
@@ -365,14 +365,14 @@
static struct serio_driver serio_raw_drv = {
.driver = {
- .name = "serio_raw",
+ .name = "serio_raw",
+ .manual_bind = 1,
},
.description = DRIVER_DESC,
.interrupt = serio_raw_interrupt,
.connect = serio_raw_connect,
.reconnect = serio_raw_reconnect,
.disconnect = serio_raw_disconnect,
- .manual_bind = 1,
};
int __init serio_raw_init(void)
diff -urN a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2004-11-16 02:20:53 -0500
+++ b/include/linux/device.h 2004-11-16 02:20:53 -0500
@@ -102,6 +102,8 @@
char * name;
struct bus_type * bus;
+ unsigned int manual_bind;
+
struct semaphore unload_sem;
struct kobject kobj;
struct list_head devices;
@@ -264,6 +266,9 @@
struct bus_type * bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
+ unsigned int manual_bind; /* indicates whether the core will
+ try to find a driver for the
+ device automatically */
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data (e.g. ACPI,
BIOS data relevant to device) */
diff -urN a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h 2004-11-16 02:20:53 -0500
+++ b/include/linux/serio.h 2004-11-16 02:20:53 -0500
@@ -27,8 +27,6 @@
char name[32];
char phys[32];
- unsigned int manual_bind;
-
unsigned short idbus;
unsigned short idvendor;
unsigned short idproduct;
@@ -57,8 +55,6 @@
void *private;
char *description;
- unsigned int manual_bind;
-
void (*write_wakeup)(struct serio *);
irqreturn_t (*interrupt)(struct serio *, unsigned char,
unsigned int, struct pt_regs *);
next prev parent reply other threads:[~2004-11-16 23:27 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-11-09 22:37 [RFC] [PATCH] driver core: allow userspace to unbind drivers from devices Greg KH
2004-11-09 23:36 ` Dmitry Torokhov
2004-11-10 0:33 ` Greg KH
2004-11-10 3:49 ` Dmitry Torokhov
2004-11-16 5:54 ` Greg KH
2004-11-16 20:43 ` Dmitry Torokhov [this message]
2004-11-16 23:08 ` Greg KH
2004-11-17 7:00 ` Dmitry Torokhov
2004-11-17 17:55 ` Greg KH
2004-11-16 6:13 ` Adam Belay
2004-11-16 6:37 ` Dmitry Torokhov
2004-11-16 7:04 ` Adam Belay
2004-11-16 20:22 ` Greg KH
2004-11-16 21:09 ` Dmitry Torokhov
2004-11-16 20:17 ` Greg KH
2004-11-17 7:07 ` Dmitry Torokhov
2004-11-17 17:53 ` Greg KH
2004-11-17 19:01 ` Dmitry Torokhov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d120d50004111612437ebe76d9@mail.gmail.com \
--to=dmitry.torokhov@gmail.com \
--cc=ambx1@neo.rr.com \
--cc=dtor_core@ameritech.net \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mochel@digitalimplant.org \
--cc=tj@home-tj.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox