aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/misc.c22
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 */
63static unsigned char misc_minors[DYNAMIC_MINORS / 8]; 63static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS);
64 64
65#ifdef CONFIG_PROC_FS 65#ifdef CONFIG_PROC_FS
66static void *misc_seq_start(struct seq_file *seq, loff_t *pos) 66static 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
244int misc_deregister(struct miscdevice *misc) 240int 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}