1 /* 2 * linux/fs/char_dev.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 */ 6 7 #include <linux/config.h> 8 #include <linux/init.h> 9 #include <linux/fs.h> 10 #include <linux/slab.h> 11 #include <linux/string.h> 12 13 #include <linux/major.h> 14 #include <linux/errno.h> 15 #include <linux/module.h> 16 #include <linux/smp_lock.h> 17 #include <linux/devfs_fs_kernel.h> 18 19 #include <linux/kobject.h> 20 #include <linux/kobj_map.h> 21 #include <linux/cdev.h> 22 23 #ifdef CONFIG_KMOD 24 #include <linux/kmod.h> 25 #endif 26 27 static struct kobj_map *cdev_map; 28 29 #define MAX_PROBE_HASH 255 /* random */ 30 31 static DECLARE_MUTEX(chrdevs_lock); 32 33 static struct char_device_struct { 34 struct char_device_struct *next; 35 unsigned int major; 36 unsigned int baseminor; 37 int minorct; 38 char name[64]; 39 struct file_operations *fops; 40 struct cdev *cdev; /* will die */ 41 } *chrdevs[MAX_PROBE_HASH]; 42 43 /* index in the above */ 44 static inline int major_to_index(int major) 45 { 46 return major % MAX_PROBE_HASH; 47 } 48 49 struct chrdev_info { 50 int index; 51 struct char_device_struct *cd; 52 }; 53 54 void *get_next_chrdev(void *dev) 55 { 56 struct chrdev_info *info; 57 58 if (dev == NULL) { 59 info = kmalloc(sizeof(*info), GFP_KERNEL); 60 if (!info) 61 goto out; 62 info->index=0; 63 info->cd = chrdevs[info->index]; 64 if (info->cd) 65 goto out; 66 } else { 67 info = dev; 68 } 69 70 while (info->index < ARRAY_SIZE(chrdevs)) { 71 if (info->cd) 72 info->cd = info->cd->next; 73 if (info->cd) 74 goto out; 75 /* 76 * No devices on this chain, move to the next 77 */ 78 info->index++; 79 info->cd = (info->index < ARRAY_SIZE(chrdevs)) ? 80 chrdevs[info->index] : NULL; 81 if (info->cd) 82 goto out; 83 } 84 85 out: 86 return info; 87 } 88 89 void *acquire_chrdev_list(void) 90 { 91 down(&chrdevs_lock); 92 return get_next_chrdev(NULL); 93 } 94 95 void release_chrdev_list(void *dev) 96 { 97 up(&chrdevs_lock); 98 kfree(dev); 99 } 100 101 102 int count_chrdev_list(void) 103 { 104 struct char_device_struct *cd; 105 int i, count; 106 107 count = 0; 108 109 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { 110 for (cd = chrdevs[i]; cd; cd = cd->next) 111 count++; 112 } 113 114 return count; 115 } 116 117 int get_chrdev_info(void *dev, int *major, char **name) 118 { 119 struct chrdev_info *info = dev; 120 121 if (info->cd == NULL) 122 return 1; 123 124 *major = info->cd->major; 125 *name = info->cd->name; 126 return 0; 127 } 128 129 /* 130 * Register a single major with a specified minor range. 131 * 132 * If major == 0 this functions will dynamically allocate a major and return 133 * its number. 134 * 135 * If major > 0 this function will attempt to reserve the passed range of 136 * minors and will return zero on success. 137 * 138 * Returns a -ve errno on failure. 139 */ 140 static struct char_device_struct * 141 __register_chrdev_region(unsigned int major, unsigned int baseminor, 142 int minorct, const char *name) 143 { 144 struct char_device_struct *cd, **cp; 145 int ret = 0; 146 int i; 147 148 cd = kmalloc(sizeof(struct char_device_struct), GFP_KERNEL); 149 if (cd == NULL) 150 return ERR_PTR(-ENOMEM); 151 152 memset(cd, 0, sizeof(struct char_device_struct)); 153 154 down(&chrdevs_lock); 155 156 /* temporary */ 157 if (major == 0) { 158 for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) { 159 if (chrdevs[i] == NULL) 160 break; 161 } 162 163 if (i == 0) { 164 ret = -EBUSY; 165 goto out; 166 } 167 major = i; 168 ret = major; 169 } 170 171 cd->major = major; 172 cd->baseminor = baseminor; 173 cd->minorct = minorct; 174 strncpy(cd->name,name, 64); 175 176 i = major_to_index(major); 177 178 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) 179 if ((*cp)->major > major || 180 ((*cp)->major == major && (*cp)->baseminor >= baseminor)) 181 break; 182 if (*cp && (*cp)->major == major && 183 (*cp)->baseminor < baseminor + minorct) { 184 ret = -EBUSY; 185 goto out; 186 } 187 cd->next = *cp; 188 *cp = cd; 189 up(&chrdevs_lock); 190 return cd; 191 out: 192 up(&chrdevs_lock); 193 kfree(cd); 194 return ERR_PTR(ret); 195 } 196 197 static struct char_device_struct * 198 __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) 199 { 200 struct char_device_struct *cd = NULL, **cp; 201 int i = major_to_index(major); 202 203 down(&chrdevs_lock); 204 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) 205 if ((*cp)->major == major && 206 (*cp)->baseminor == baseminor && 207 (*cp)->minorct == minorct) 208 break; 209 if (*cp) { 210 cd = *cp; 211 *cp = cd->next; 212 } 213 up(&chrdevs_lock); 214 return cd; 215 } 216 217 int register_chrdev_region(dev_t from, unsigned count, const char *name) 218 { 219 struct char_device_struct *cd; 220 dev_t to = from + count; 221 dev_t n, next; 222 223 for (n = from; n < to; n = next) { 224 next = MKDEV(MAJOR(n)+1, 0); 225 if (next > to) 226 next = to; 227 cd = __register_chrdev_region(MAJOR(n), MINOR(n), 228 next - n, name); 229 if (IS_ERR(cd)) 230 goto fail; 231 } 232 return 0; 233 fail: 234 to = n; 235 for (n = from; n < to; n = next) { 236 next = MKDEV(MAJOR(n)+1, 0); 237 kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n)); 238 } 239 return PTR_ERR(cd); 240 } 241 242 int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, 243 const char *name) 244 { 245 struct char_device_struct *cd; 246 cd = __register_chrdev_region(0, baseminor, count, name); 247 if (IS_ERR(cd)) 248 return PTR_ERR(cd); 249 *dev = MKDEV(cd->major, cd->baseminor); 250 return 0; 251 } 252 253 int register_chrdev(unsigned int major, const char *name, 254 struct file_operations *fops) 255 { 256 struct char_device_struct *cd; 257 struct cdev *cdev; 258 char *s; 259 int err = -ENOMEM; 260 261 cd = __register_chrdev_region(major, 0, 256, name); 262 if (IS_ERR(cd)) 263 return PTR_ERR(cd); 264 265 cdev = cdev_alloc(); 266 if (!cdev) 267 goto out2; 268 269 cdev->owner = fops->owner; 270 cdev->ops = fops; 271 kobject_set_name(&cdev->kobj, "%s", name); 272 for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) 273 *s = '!'; 274 275 err = cdev_add(cdev, MKDEV(cd->major, 0), 256); 276 if (err) 277 goto out; 278 279 cd->cdev = cdev; 280 281 return major ? 0 : cd->major; 282 out: 283 kobject_put(&cdev->kobj); 284 out2: 285 kfree(__unregister_chrdev_region(cd->major, 0, 256)); 286 return err; 287 } 288 289 void unregister_chrdev_region(dev_t from, unsigned count) 290 { 291 dev_t to = from + count; 292 dev_t n, next; 293 294 for (n = from; n < to; n = next) { 295 next = MKDEV(MAJOR(n)+1, 0); 296 if (next > to) 297 next = to; 298 kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n)); 299 } 300 } 301 302 int unregister_chrdev(unsigned int major, const char *name) 303 { 304 struct char_device_struct *cd; 305 cd = __unregister_chrdev_region(major, 0, 256); 306 if (cd && cd->cdev) 307 cdev_del(cd->cdev); 308 kfree(cd); 309 return 0; 310 } 311 312 static DEFINE_SPINLOCK(cdev_lock); 313 314 static struct kobject *cdev_get(struct cdev *p) 315 { 316 struct module *owner = p->owner; 317 struct kobject *kobj; 318 319 if (owner && !try_module_get(owner)) 320 return NULL; 321 kobj = kobject_get(&p->kobj); 322 if (!kobj) 323 module_put(owner); 324 return kobj; 325 } 326 327 void cdev_put(struct cdev *p) 328 { 329 if (p) { 330 struct module *owner = p->owner; 331 kobject_put(&p->kobj); 332 module_put(owner); 333 } 334 } 335 336 /* 337 * Called every time a character special file is opened 338 */ 339 int chrdev_open(struct inode * inode, struct file * filp) 340 { 341 struct cdev *p; 342 struct cdev *new = NULL; 343 int ret = 0; 344 345 spin_lock(&cdev_lock); 346 p = inode->i_cdev; 347 if (!p) { 348 struct kobject *kobj; 349 int idx; 350 spin_unlock(&cdev_lock); 351 kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx); 352 if (!kobj) 353 return -ENXIO; 354 new = container_of(kobj, struct cdev, kobj); 355 spin_lock(&cdev_lock); 356 p = inode->i_cdev; 357 if (!p) { 358 inode->i_cdev = p = new; 359 inode->i_cindex = idx; 360 list_add(&inode->i_devices, &p->list); 361 new = NULL; 362 } else if (!cdev_get(p)) 363 ret = -ENXIO; 364 } else if (!cdev_get(p)) 365 ret = -ENXIO; 366 spin_unlock(&cdev_lock); 367 cdev_put(new); 368 if (ret) 369 return ret; 370 filp->f_op = fops_get(p->ops); 371 if (!filp->f_op) { 372 cdev_put(p); 373 return -ENXIO; 374 } 375 if (filp->f_op->open) { 376 lock_kernel(); 377 ret = filp->f_op->open(inode,filp); 378 unlock_kernel(); 379 } 380 if (ret) 381 cdev_put(p); 382 return ret; 383 } 384 385 void cd_forget(struct inode *inode) 386 { 387 spin_lock(&cdev_lock); 388 list_del_init(&inode->i_devices); 389 inode->i_cdev = NULL; 390 spin_unlock(&cdev_lock); 391 } 392 393 static void cdev_purge(struct cdev *cdev) 394 { 395 spin_lock(&cdev_lock); 396 while (!list_empty(&cdev->list)) { 397 struct inode *inode; 398 inode = container_of(cdev->list.next, struct inode, i_devices); 399 list_del_init(&inode->i_devices); 400 inode->i_cdev = NULL; 401 } 402 spin_unlock(&cdev_lock); 403 } 404 405 /* 406 * Dummy default file-operations: the only thing this does 407 * is contain the open that then fills in the correct operations 408 * depending on the special file... 409 */ 410 struct file_operations def_chr_fops = { 411 .open = chrdev_open, 412 }; 413 414 static struct kobject *exact_match(dev_t dev, int *part, void *data) 415 { 416 struct cdev *p = data; 417 return &p->kobj; 418 } 419 420 static int exact_lock(dev_t dev, void *data) 421 { 422 struct cdev *p = data; 423 return cdev_get(p) ? 0 : -1; 424 } 425 426 int cdev_add(struct cdev *p, dev_t dev, unsigned count) 427 { 428 p->dev = dev; 429 p->count = count; 430 return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); 431 } 432 433 static void cdev_unmap(dev_t dev, unsigned count) 434 { 435 kobj_unmap(cdev_map, dev, count); 436 } 437 438 void cdev_del(struct cdev *p) 439 { 440 cdev_unmap(p->dev, p->count); 441 kobject_put(&p->kobj); 442 } 443 444 445 static void cdev_default_release(struct kobject *kobj) 446 { 447 struct cdev *p = container_of(kobj, struct cdev, kobj); 448 cdev_purge(p); 449 } 450 451 static void cdev_dynamic_release(struct kobject *kobj) 452 { 453 struct cdev *p = container_of(kobj, struct cdev, kobj); 454 cdev_purge(p); 455 kfree(p); 456 } 457 458 static struct kobj_type ktype_cdev_default = { 459 .release = cdev_default_release, 460 }; 461 462 static struct kobj_type ktype_cdev_dynamic = { 463 .release = cdev_dynamic_release, 464 }; 465 466 struct cdev *cdev_alloc(void) 467 { 468 struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL); 469 if (p) { 470 memset(p, 0, sizeof(struct cdev)); 471 p->kobj.ktype = &ktype_cdev_dynamic; 472 INIT_LIST_HEAD(&p->list); 473 kobject_init(&p->kobj); 474 } 475 return p; 476 } 477 478 void cdev_init(struct cdev *cdev, struct file_operations *fops) 479 { 480 memset(cdev, 0, sizeof *cdev); 481 INIT_LIST_HEAD(&cdev->list); 482 cdev->kobj.ktype = &ktype_cdev_default; 483 kobject_init(&cdev->kobj); 484 cdev->ops = fops; 485 } 486 487 static struct kobject *base_probe(dev_t dev, int *part, void *data) 488 { 489 if (request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0) 490 /* Make old-style 2.4 aliases work */ 491 request_module("char-major-%d", MAJOR(dev)); 492 return NULL; 493 } 494 495 void __init chrdev_init(void) 496 { 497 cdev_map = kobj_map_init(base_probe, &chrdevs_lock); 498 } 499 500 501 /* Let modules do char dev stuff */ 502 EXPORT_SYMBOL(register_chrdev_region); 503 EXPORT_SYMBOL(unregister_chrdev_region); 504 EXPORT_SYMBOL(alloc_chrdev_region); 505 EXPORT_SYMBOL(cdev_init); 506 EXPORT_SYMBOL(cdev_alloc); 507 EXPORT_SYMBOL(cdev_del); 508 EXPORT_SYMBOL(cdev_add); 509 EXPORT_SYMBOL(register_chrdev); 510 EXPORT_SYMBOL(unregister_chrdev); 511