diff options
Diffstat (limited to 'drivers/char/misc.c')
-rw-r--r-- | drivers/char/misc.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 07fa612a58d5..94a136e96c06 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/device.h> | 49 | #include <linux/device.h> |
50 | #include <linux/tty.h> | 50 | #include <linux/tty.h> |
51 | #include <linux/kmod.h> | 51 | #include <linux/kmod.h> |
52 | #include <linux/smp_lock.h> | ||
53 | 52 | ||
54 | /* | 53 | /* |
55 | * Head entry for the doubly linked miscdevice list | 54 | * Head entry for the doubly linked miscdevice list |
@@ -61,9 +60,7 @@ static DEFINE_MUTEX(misc_mtx); | |||
61 | * Assigned numbers, used for dynamic minors | 60 | * Assigned numbers, used for dynamic minors |
62 | */ | 61 | */ |
63 | #define DYNAMIC_MINORS 64 /* like dynamic majors */ | 62 | #define DYNAMIC_MINORS 64 /* like dynamic majors */ |
64 | static unsigned char misc_minors[DYNAMIC_MINORS / 8]; | 63 | static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS); |
65 | |||
66 | extern int pmu_device_init(void); | ||
67 | 64 | ||
68 | #ifdef CONFIG_PROC_FS | 65 | #ifdef CONFIG_PROC_FS |
69 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) | 66 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) |
@@ -118,8 +115,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
118 | struct miscdevice *c; | 115 | struct miscdevice *c; |
119 | int err = -ENODEV; | 116 | int err = -ENODEV; |
120 | const struct file_operations *old_fops, *new_fops = NULL; | 117 | const struct file_operations *old_fops, *new_fops = NULL; |
121 | 118 | ||
122 | lock_kernel(); | ||
123 | mutex_lock(&misc_mtx); | 119 | mutex_lock(&misc_mtx); |
124 | 120 | ||
125 | list_for_each_entry(c, &misc_list, list) { | 121 | list_for_each_entry(c, &misc_list, list) { |
@@ -157,7 +153,6 @@ static int misc_open(struct inode * inode, struct file * file) | |||
157 | fops_put(old_fops); | 153 | fops_put(old_fops); |
158 | fail: | 154 | fail: |
159 | mutex_unlock(&misc_mtx); | 155 | mutex_unlock(&misc_mtx); |
160 | unlock_kernel(); | ||
161 | return err; | 156 | return err; |
162 | } | 157 | } |
163 | 158 | ||
@@ -201,24 +196,23 @@ int misc_register(struct miscdevice * misc) | |||
201 | } | 196 | } |
202 | 197 | ||
203 | if (misc->minor == MISC_DYNAMIC_MINOR) { | 198 | if (misc->minor == MISC_DYNAMIC_MINOR) { |
204 | int i = DYNAMIC_MINORS; | 199 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); |
205 | while (--i >= 0) | 200 | if (i >= DYNAMIC_MINORS) { |
206 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) | ||
207 | break; | ||
208 | if (i<0) { | ||
209 | mutex_unlock(&misc_mtx); | 201 | mutex_unlock(&misc_mtx); |
210 | return -EBUSY; | 202 | return -EBUSY; |
211 | } | 203 | } |
212 | misc->minor = i; | 204 | misc->minor = DYNAMIC_MINORS - i - 1; |
205 | set_bit(i, misc_minors); | ||
213 | } | 206 | } |
214 | 207 | ||
215 | if (misc->minor < DYNAMIC_MINORS) | ||
216 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); | ||
217 | dev = MKDEV(MISC_MAJOR, misc->minor); | 208 | dev = MKDEV(MISC_MAJOR, misc->minor); |
218 | 209 | ||
219 | misc->this_device = device_create(misc_class, misc->parent, dev, | 210 | misc->this_device = device_create(misc_class, misc->parent, dev, |
220 | misc, "%s", misc->name); | 211 | misc, "%s", misc->name); |
221 | if (IS_ERR(misc->this_device)) { | 212 | if (IS_ERR(misc->this_device)) { |
213 | int i = DYNAMIC_MINORS - misc->minor - 1; | ||
214 | if (i < DYNAMIC_MINORS && i >= 0) | ||
215 | clear_bit(i, misc_minors); | ||
222 | err = PTR_ERR(misc->this_device); | 216 | err = PTR_ERR(misc->this_device); |
223 | goto out; | 217 | goto out; |
224 | } | 218 | } |
@@ -245,7 +239,7 @@ int misc_register(struct miscdevice * misc) | |||
245 | 239 | ||
246 | int misc_deregister(struct miscdevice *misc) | 240 | int misc_deregister(struct miscdevice *misc) |
247 | { | 241 | { |
248 | int i = misc->minor; | 242 | int i = DYNAMIC_MINORS - misc->minor - 1; |
249 | 243 | ||
250 | if (list_empty(&misc->list)) | 244 | if (list_empty(&misc->list)) |
251 | return -EINVAL; | 245 | return -EINVAL; |
@@ -253,9 +247,8 @@ int misc_deregister(struct miscdevice *misc) | |||
253 | mutex_lock(&misc_mtx); | 247 | mutex_lock(&misc_mtx); |
254 | list_del(&misc->list); | 248 | list_del(&misc->list); |
255 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 249 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
256 | if (i < DYNAMIC_MINORS && i>0) { | 250 | if (i < DYNAMIC_MINORS && i >= 0) |
257 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); | 251 | clear_bit(i, misc_minors); |
258 | } | ||
259 | mutex_unlock(&misc_mtx); | 252 | mutex_unlock(&misc_mtx); |
260 | return 0; | 253 | return 0; |
261 | } | 254 | } |