diff options
Diffstat (limited to 'drivers/char/misc.c')
-rw-r--r-- | drivers/char/misc.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 9fd5a91e0d81..fdb0f9b3fe45 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -117,14 +117,14 @@ static int misc_open(struct inode * inode, struct file * file) | |||
117 | const struct file_operations *new_fops = NULL; | 117 | const struct file_operations *new_fops = NULL; |
118 | 118 | ||
119 | mutex_lock(&misc_mtx); | 119 | mutex_lock(&misc_mtx); |
120 | 120 | ||
121 | list_for_each_entry(c, &misc_list, list) { | 121 | list_for_each_entry(c, &misc_list, list) { |
122 | if (c->minor == minor) { | 122 | if (c->minor == minor) { |
123 | new_fops = fops_get(c->fops); | 123 | new_fops = fops_get(c->fops); |
124 | break; | 124 | break; |
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | if (!new_fops) { | 128 | if (!new_fops) { |
129 | mutex_unlock(&misc_mtx); | 129 | mutex_unlock(&misc_mtx); |
130 | request_module("char-major-%d-%d", MISC_MAJOR, minor); | 130 | request_module("char-major-%d-%d", MISC_MAJOR, minor); |
@@ -167,7 +167,7 @@ static const struct file_operations misc_fops = { | |||
167 | /** | 167 | /** |
168 | * misc_register - register a miscellaneous device | 168 | * misc_register - register a miscellaneous device |
169 | * @misc: device structure | 169 | * @misc: device structure |
170 | * | 170 | * |
171 | * Register a miscellaneous device with the kernel. If the minor | 171 | * Register a miscellaneous device with the kernel. If the minor |
172 | * number is set to %MISC_DYNAMIC_MINOR a minor number is assigned | 172 | * number is set to %MISC_DYNAMIC_MINOR a minor number is assigned |
173 | * and placed in the minor field of the structure. For other cases | 173 | * and placed in the minor field of the structure. For other cases |
@@ -181,17 +181,18 @@ static const struct file_operations misc_fops = { | |||
181 | * A zero is returned on success and a negative errno code for | 181 | * A zero is returned on success and a negative errno code for |
182 | * failure. | 182 | * failure. |
183 | */ | 183 | */ |
184 | 184 | ||
185 | int misc_register(struct miscdevice * misc) | 185 | int misc_register(struct miscdevice * misc) |
186 | { | 186 | { |
187 | dev_t dev; | 187 | dev_t dev; |
188 | int err = 0; | 188 | int err = 0; |
189 | bool is_dynamic = (misc->minor == MISC_DYNAMIC_MINOR); | ||
189 | 190 | ||
190 | INIT_LIST_HEAD(&misc->list); | 191 | INIT_LIST_HEAD(&misc->list); |
191 | 192 | ||
192 | mutex_lock(&misc_mtx); | 193 | mutex_lock(&misc_mtx); |
193 | 194 | ||
194 | if (misc->minor == MISC_DYNAMIC_MINOR) { | 195 | if (is_dynamic) { |
195 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); | 196 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); |
196 | if (i >= DYNAMIC_MINORS) { | 197 | if (i >= DYNAMIC_MINORS) { |
197 | err = -EBUSY; | 198 | err = -EBUSY; |
@@ -216,9 +217,13 @@ int misc_register(struct miscdevice * misc) | |||
216 | device_create_with_groups(misc_class, misc->parent, dev, | 217 | device_create_with_groups(misc_class, misc->parent, dev, |
217 | misc, misc->groups, "%s", misc->name); | 218 | misc, misc->groups, "%s", misc->name); |
218 | if (IS_ERR(misc->this_device)) { | 219 | if (IS_ERR(misc->this_device)) { |
219 | int i = DYNAMIC_MINORS - misc->minor - 1; | 220 | if (is_dynamic) { |
220 | if (i < DYNAMIC_MINORS && i >= 0) | 221 | int i = DYNAMIC_MINORS - misc->minor - 1; |
221 | clear_bit(i, misc_minors); | 222 | |
223 | if (i < DYNAMIC_MINORS && i >= 0) | ||
224 | clear_bit(i, misc_minors); | ||
225 | misc->minor = MISC_DYNAMIC_MINOR; | ||
226 | } | ||
222 | err = PTR_ERR(misc->this_device); | 227 | err = PTR_ERR(misc->this_device); |
223 | goto out; | 228 | goto out; |
224 | } | 229 | } |