diff options
-rw-r--r-- | drivers/char/misc.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index a3a02f6303c8..94a136e96c06 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -60,7 +60,7 @@ static DEFINE_MUTEX(misc_mtx); | |||
60 | * Assigned numbers, used for dynamic minors | 60 | * Assigned numbers, used for dynamic minors |
61 | */ | 61 | */ |
62 | #define DYNAMIC_MINORS 64 /* like dynamic majors */ | 62 | #define DYNAMIC_MINORS 64 /* like dynamic majors */ |
63 | static unsigned char misc_minors[DYNAMIC_MINORS / 8]; | 63 | static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS); |
64 | 64 | ||
65 | #ifdef CONFIG_PROC_FS | 65 | #ifdef CONFIG_PROC_FS |
66 | 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) |
@@ -196,27 +196,23 @@ int misc_register(struct miscdevice * misc) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | if (misc->minor == MISC_DYNAMIC_MINOR) { | 198 | if (misc->minor == MISC_DYNAMIC_MINOR) { |
199 | int i = DYNAMIC_MINORS; | 199 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); |
200 | while (--i >= 0) | 200 | if (i >= DYNAMIC_MINORS) { |
201 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) | ||
202 | break; | ||
203 | if (i<0) { | ||
204 | mutex_unlock(&misc_mtx); | 201 | mutex_unlock(&misc_mtx); |
205 | return -EBUSY; | 202 | return -EBUSY; |
206 | } | 203 | } |
207 | misc->minor = i; | 204 | misc->minor = DYNAMIC_MINORS - i - 1; |
205 | set_bit(i, misc_minors); | ||
208 | } | 206 | } |
209 | 207 | ||
210 | if (misc->minor < DYNAMIC_MINORS) | ||
211 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); | ||
212 | dev = MKDEV(MISC_MAJOR, misc->minor); | 208 | dev = MKDEV(MISC_MAJOR, misc->minor); |
213 | 209 | ||
214 | misc->this_device = device_create(misc_class, misc->parent, dev, | 210 | misc->this_device = device_create(misc_class, misc->parent, dev, |
215 | misc, "%s", misc->name); | 211 | misc, "%s", misc->name); |
216 | if (IS_ERR(misc->this_device)) { | 212 | if (IS_ERR(misc->this_device)) { |
217 | int i = misc->minor; | 213 | int i = DYNAMIC_MINORS - misc->minor - 1; |
218 | if (i < DYNAMIC_MINORS && i >= 0) | 214 | if (i < DYNAMIC_MINORS && i >= 0) |
219 | misc_minors[i>>3] &= ~(1 << (i & 7)); | 215 | clear_bit(i, misc_minors); |
220 | err = PTR_ERR(misc->this_device); | 216 | err = PTR_ERR(misc->this_device); |
221 | goto out; | 217 | goto out; |
222 | } | 218 | } |
@@ -243,7 +239,7 @@ int misc_register(struct miscdevice * misc) | |||
243 | 239 | ||
244 | int misc_deregister(struct miscdevice *misc) | 240 | int misc_deregister(struct miscdevice *misc) |
245 | { | 241 | { |
246 | int i = misc->minor; | 242 | int i = DYNAMIC_MINORS - misc->minor - 1; |
247 | 243 | ||
248 | if (list_empty(&misc->list)) | 244 | if (list_empty(&misc->list)) |
249 | return -EINVAL; | 245 | return -EINVAL; |
@@ -252,7 +248,7 @@ int misc_deregister(struct miscdevice *misc) | |||
252 | list_del(&misc->list); | 248 | list_del(&misc->list); |
253 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 249 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
254 | if (i < DYNAMIC_MINORS && i >= 0) | 250 | if (i < DYNAMIC_MINORS && i >= 0) |
255 | misc_minors[i>>3] &= ~(1 << (i & 7)); | 251 | clear_bit(i, misc_minors); |
256 | mutex_unlock(&misc_mtx); | 252 | mutex_unlock(&misc_mtx); |
257 | return 0; | 253 | return 0; |
258 | } | 254 | } |