Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
455 | giacomo | 1 | /* |
2 | * driver.c - centralized device driver management |
||
3 | * |
||
4 | * Copyright (c) 2002-3 Patrick Mochel |
||
5 | * Copyright (c) 2002-3 Open Source Development Labs |
||
6 | * |
||
7 | * This file is released under the GPLv2 |
||
8 | * |
||
9 | */ |
||
10 | |||
11 | #undef DEBUG |
||
12 | |||
13 | #include <linuxcomp.h> |
||
14 | |||
15 | #include <linux/device.h> |
||
16 | #include <linux/module.h> |
||
17 | #include <linux/errno.h> |
||
18 | #include <linux/string.h> |
||
19 | #include "base.h" |
||
20 | |||
21 | #define to_dev(node) container_of(node,struct device,driver_list) |
||
22 | #define to_drv(obj) container_of(obj,struct device_driver,kobj) |
||
23 | |||
24 | /** |
||
25 | * driver_create_file - create sysfs file for driver. |
||
26 | * @drv: driver. |
||
27 | * @attr: driver attribute descriptor. |
||
28 | */ |
||
29 | |||
30 | int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) |
||
31 | { |
||
32 | int error; |
||
33 | if (get_driver(drv)) { |
||
34 | error = 0;//sysfs_create_file(&drv->kobj,&attr->attr); |
||
35 | put_driver(drv); |
||
36 | } else |
||
37 | error = -EINVAL; |
||
38 | return error; |
||
39 | } |
||
40 | |||
41 | |||
42 | /** |
||
43 | * driver_remove_file - remove sysfs file for driver. |
||
44 | * @drv: driver. |
||
45 | * @attr: driver attribute descriptor. |
||
46 | */ |
||
47 | |||
48 | void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) |
||
49 | { |
||
50 | if (get_driver(drv)) { |
||
51 | //sysfs_remove_file(&drv->kobj,&attr->attr); |
||
52 | put_driver(drv); |
||
53 | } |
||
54 | } |
||
55 | |||
56 | |||
57 | /** |
||
58 | * get_driver - increment driver reference count. |
||
59 | * @drv: driver. |
||
60 | */ |
||
61 | struct device_driver * get_driver(struct device_driver * drv) |
||
62 | { |
||
63 | return drv ? to_drv(kobject_get(&drv->kobj)) : NULL; |
||
64 | } |
||
65 | |||
66 | |||
67 | /** |
||
68 | * put_driver - decrement driver's refcount. |
||
69 | * @drv: driver. |
||
70 | */ |
||
71 | void put_driver(struct device_driver * drv) |
||
72 | { |
||
73 | kobject_put(&drv->kobj); |
||
74 | } |
||
75 | |||
76 | |||
77 | /** |
||
78 | * driver_register - register driver with bus |
||
79 | * @drv: driver to register |
||
80 | * |
||
81 | * We pass off most of the work to the bus_add_driver() call, |
||
82 | * since most of the things we have to do deal with the bus |
||
83 | * structures. |
||
84 | * |
||
85 | * The one interesting aspect is that we initialize @drv->unload_sem |
||
86 | * to a locked state here. It will be unlocked when the driver |
||
87 | * reference count reaches 0. |
||
88 | */ |
||
89 | int driver_register(struct device_driver * drv) |
||
90 | { |
||
91 | INIT_LIST_HEAD(&drv->devices); |
||
92 | //init_MUTEX_LOCKED(&drv->unload_sem); |
||
93 | return bus_add_driver(drv); |
||
94 | } |
||
95 | |||
96 | |||
97 | /** |
||
98 | * driver_unregister - remove driver from system. |
||
99 | * @drv: driver. |
||
100 | * |
||
101 | * Again, we pass off most of the work to the bus-level call. |
||
102 | * |
||
103 | * Though, once that is done, we attempt to take @drv->unload_sem. |
||
104 | * This will block until the driver refcount reaches 0, and it is |
||
105 | * released. Only modular drivers will call this function, and we |
||
106 | * have to guarantee that it won't complete, letting the driver |
||
107 | * unload until all references are gone. |
||
108 | */ |
||
109 | |||
110 | void driver_unregister(struct device_driver * drv) |
||
111 | { |
||
112 | bus_remove_driver(drv); |
||
113 | //down(&drv->unload_sem); |
||
114 | //up(&drv->unload_sem); |
||
115 | } |
||
116 | |||
117 | EXPORT_SYMBOL(driver_register); |
||
118 | EXPORT_SYMBOL(driver_unregister); |
||
119 | EXPORT_SYMBOL(get_driver); |
||
120 | EXPORT_SYMBOL(put_driver); |
||
121 | |||
122 | EXPORT_SYMBOL(driver_create_file); |
||
123 | EXPORT_SYMBOL(driver_remove_file); |