aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/dd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r--drivers/base/dd.c147
1 files changed, 110 insertions, 37 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 889c71111239..b5f43c3e44fa 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kthread.h>
20 21
21#include "base.h" 22#include "base.h"
22#include "power/power.h" 23#include "power/power.h"
@@ -38,66 +39,73 @@
38 * 39 *
39 * This function must be called with @dev->sem held. 40 * This function must be called with @dev->sem held.
40 */ 41 */
41void device_bind_driver(struct device * dev) 42int device_bind_driver(struct device *dev)
42{ 43{
43 if (klist_node_attached(&dev->knode_driver)) 44 int ret;
44 return; 45
46 if (klist_node_attached(&dev->knode_driver)) {
47 printk(KERN_WARNING "%s: device %s already bound\n",
48 __FUNCTION__, kobject_name(&dev->kobj));
49 return 0;
50 }
45 51
46 pr_debug("bound device '%s' to driver '%s'\n", 52 pr_debug("bound device '%s' to driver '%s'\n",
47 dev->bus_id, dev->driver->name); 53 dev->bus_id, dev->driver->name);
48 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); 54 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
49 sysfs_create_link(&dev->driver->kobj, &dev->kobj, 55 ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
50 kobject_name(&dev->kobj)); 56 kobject_name(&dev->kobj));
51 sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); 57 if (ret == 0) {
58 ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj,
59 "driver");
60 if (ret)
61 sysfs_remove_link(&dev->driver->kobj,
62 kobject_name(&dev->kobj));
63 }
64 return ret;
52} 65}
53 66
54/** 67struct stupid_thread_structure {
55 * driver_probe_device - attempt to bind device & driver. 68 struct device_driver *drv;
56 * @drv: driver. 69 struct device *dev;
57 * @dev: device. 70};
58 * 71
59 * First, we call the bus's match function, if one present, which 72static atomic_t probe_count = ATOMIC_INIT(0);
60 * should compare the device IDs the driver supports with the 73static int really_probe(void *void_data)
61 * device IDs of the device. Note we don't do this ourselves
62 * because we don't know the format of the ID structures, nor what
63 * is to be considered a match and what is not.
64 *
65 * This function returns 1 if a match is found, an error if one
66 * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
67 *
68 * This function must be called with @dev->sem held. When called
69 * for a USB interface, @dev->parent->sem must be held as well.
70 */
71int driver_probe_device(struct device_driver * drv, struct device * dev)
72{ 74{
75 struct stupid_thread_structure *data = void_data;
76 struct device_driver *drv = data->drv;
77 struct device *dev = data->dev;
73 int ret = 0; 78 int ret = 0;
74 79
75 if (drv->bus->match && !drv->bus->match(dev, drv)) 80 atomic_inc(&probe_count);
76 goto Done; 81 pr_debug("%s: Probing driver %s with device %s\n",
82 drv->bus->name, drv->name, dev->bus_id);
77 83
78 pr_debug("%s: Matched Device %s with Driver %s\n",
79 drv->bus->name, dev->bus_id, drv->name);
80 dev->driver = drv; 84 dev->driver = drv;
81 if (dev->bus->probe) { 85 if (dev->bus->probe) {
82 ret = dev->bus->probe(dev); 86 ret = dev->bus->probe(dev);
83 if (ret) { 87 if (ret) {
84 dev->driver = NULL; 88 dev->driver = NULL;
85 goto ProbeFailed; 89 goto probe_failed;
86 } 90 }
87 } else if (drv->probe) { 91 } else if (drv->probe) {
88 ret = drv->probe(dev); 92 ret = drv->probe(dev);
89 if (ret) { 93 if (ret) {
90 dev->driver = NULL; 94 dev->driver = NULL;
91 goto ProbeFailed; 95 goto probe_failed;
92 } 96 }
93 } 97 }
94 device_bind_driver(dev); 98 if (device_bind_driver(dev)) {
99 printk(KERN_ERR "%s: device_bind_driver(%s) failed\n",
100 __FUNCTION__, dev->bus_id);
101 /* How does undo a ->probe? We're screwed. */
102 }
95 ret = 1; 103 ret = 1;
96 pr_debug("%s: Bound Device %s to Driver %s\n", 104 pr_debug("%s: Bound Device %s to Driver %s\n",
97 drv->bus->name, dev->bus_id, drv->name); 105 drv->bus->name, dev->bus_id, drv->name);
98 goto Done; 106 goto done;
99 107
100 ProbeFailed: 108probe_failed:
101 if (ret == -ENODEV || ret == -ENXIO) { 109 if (ret == -ENODEV || ret == -ENXIO) {
102 /* Driver matched, but didn't support device 110 /* Driver matched, but didn't support device
103 * or device not found. 111 * or device not found.
@@ -110,7 +118,71 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
110 "%s: probe of %s failed with error %d\n", 118 "%s: probe of %s failed with error %d\n",
111 drv->name, dev->bus_id, ret); 119 drv->name, dev->bus_id, ret);
112 } 120 }
113 Done: 121done:
122 kfree(data);
123 atomic_dec(&probe_count);
124 return ret;
125}
126
127/**
128 * driver_probe_done
129 * Determine if the probe sequence is finished or not.
130 *
131 * Should somehow figure out how to use a semaphore, not an atomic variable...
132 */
133int driver_probe_done(void)
134{
135 pr_debug("%s: probe_count = %d\n", __FUNCTION__,
136 atomic_read(&probe_count));
137 if (atomic_read(&probe_count))
138 return -EBUSY;
139 return 0;
140}
141
142/**
143 * driver_probe_device - attempt to bind device & driver together
144 * @drv: driver to bind a device to
145 * @dev: device to try to bind to the driver
146 *
147 * First, we call the bus's match function, if one present, which should
148 * compare the device IDs the driver supports with the device IDs of the
149 * device. Note we don't do this ourselves because we don't know the
150 * format of the ID structures, nor what is to be considered a match and
151 * what is not.
152 *
153 * This function returns 1 if a match is found, an error if one occurs
154 * (that is not -ENODEV or -ENXIO), and 0 otherwise.
155 *
156 * This function must be called with @dev->sem held. When called for a
157 * USB interface, @dev->parent->sem must be held as well.
158 */
159int driver_probe_device(struct device_driver * drv, struct device * dev)
160{
161 struct stupid_thread_structure *data;
162 struct task_struct *probe_task;
163 int ret = 0;
164
165 if (!device_is_registered(dev))
166 return -ENODEV;
167 if (drv->bus->match && !drv->bus->match(dev, drv))
168 goto done;
169
170 pr_debug("%s: Matched Device %s with Driver %s\n",
171 drv->bus->name, dev->bus_id, drv->name);
172
173 data = kmalloc(sizeof(*data), GFP_KERNEL);
174 data->drv = drv;
175 data->dev = dev;
176
177 if (drv->multithread_probe) {
178 probe_task = kthread_run(really_probe, data,
179 "probe-%s", dev->bus_id);
180 if (IS_ERR(probe_task))
181 ret = PTR_ERR(probe_task);
182 } else
183 ret = really_probe(data);
184
185done:
114 return ret; 186 return ret;
115} 187}
116 188
@@ -139,8 +211,9 @@ int device_attach(struct device * dev)
139 211
140 down(&dev->sem); 212 down(&dev->sem);
141 if (dev->driver) { 213 if (dev->driver) {
142 device_bind_driver(dev); 214 ret = device_bind_driver(dev);
143 ret = 1; 215 if (ret == 0)
216 ret = 1;
144 } else 217 } else
145 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); 218 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
146 up(&dev->sem); 219 up(&dev->sem);
@@ -182,9 +255,9 @@ static int __driver_attach(struct device * dev, void * data)
182 * returns 0 and the @dev->driver is set, we've found a 255 * returns 0 and the @dev->driver is set, we've found a
183 * compatible pair. 256 * compatible pair.
184 */ 257 */
185void driver_attach(struct device_driver * drv) 258int driver_attach(struct device_driver * drv)
186{ 259{
187 bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); 260 return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
188} 261}
189 262
190/** 263/**