phonedev.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:3k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  *            Telephony registration for Linux
  3.  *
  4.  *              (c) Copyright 1999 Red Hat Software Inc.
  5.  *
  6.  *              This program is free software; you can redistribute it and/or
  7.  *              modify it under the terms of the GNU General Public License
  8.  *              as published by the Free Software Foundation; either version
  9.  *              2 of the License, or (at your option) any later version.
  10.  *
  11.  * Author:      Alan Cox, <alan@redhat.com>
  12.  *
  13.  * Fixes:
  14.  */
  15. #include <linux/config.h>
  16. #include <linux/version.h>
  17. #include <linux/module.h>
  18. #include <linux/types.h>
  19. #include <linux/kernel.h>
  20. #include <linux/sched.h>
  21. #include <linux/mm.h>
  22. #include <linux/string.h>
  23. #include <linux/errno.h>
  24. #include <linux/phonedev.h>
  25. #include <asm/uaccess.h>
  26. #include <asm/system.h>
  27. #include <linux/kmod.h>
  28. #include <linux/autoconf.h>
  29. #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
  30. #define MODVERSIONS
  31. #endif
  32. #ifdef MODVERSIONS
  33. #include <linux/modversions.h>
  34. #endif
  35. #define PHONE_NUM_DEVICES 256
  36. /*
  37.  *    Active devices 
  38.  */
  39. static struct phone_device *phone_device[PHONE_NUM_DEVICES];
  40. /*
  41.  *    Open a phone device.
  42.  */
  43. static int phone_open(struct inode *inode, struct file *file)
  44. {
  45. unsigned int minor = MINOR(inode->i_rdev);
  46. int err;
  47. struct phone_device *p;
  48. if (minor >= PHONE_NUM_DEVICES)
  49. return -ENODEV;
  50. p = phone_device[minor];
  51. if (p == NULL) {
  52. char modname[32];
  53. sprintf(modname, "char-major-%d-%d", PHONE_MAJOR, minor);
  54. request_module(modname);
  55. p = phone_device[minor];
  56. if (p == NULL)
  57. return -ENODEV;
  58. }
  59. if (p->open) {
  60. err = p->open(p, file); /* Tell the device it is open */
  61. if (err)
  62. return err;
  63. }
  64. file->f_op = p->f_op;
  65. return 0;
  66. }
  67. /*
  68.  *    Telephony For Linux device drivers request registration here.
  69.  */
  70. int phone_register_device(struct phone_device *p, int unit)
  71. {
  72. int base;
  73. int end;
  74. int i;
  75. base = 0;
  76. end = PHONE_NUM_DEVICES - 1;
  77. if (unit != PHONE_UNIT_ANY) {
  78. base = unit;
  79. end = unit;
  80. }
  81. for (i = base; i < end; i++) {
  82. if (phone_device[i] == NULL) {
  83. phone_device[i] = p;
  84. p->minor = i;
  85. MOD_INC_USE_COUNT;
  86. return 0;
  87. }
  88. }
  89. return -ENFILE;
  90. }
  91. /*
  92.  *    Unregister an unused Telephony for linux device
  93.  */
  94. void phone_unregister_device(struct phone_device *pfd)
  95. {
  96. if (phone_device[pfd->minor] != pfd)
  97. panic("phone: bad unregister");
  98. phone_device[pfd->minor] = NULL;
  99. MOD_DEC_USE_COUNT;
  100. }
  101. static struct file_operations phone_fops =
  102. {
  103. NULL,
  104. NULL,
  105. NULL,
  106. NULL, /* readdir */
  107. NULL,
  108. NULL,
  109. NULL,
  110. phone_open,
  111. NULL, /* flush */
  112. NULL
  113. };
  114. /*
  115.  * Board init functions
  116.  */
  117.  
  118. extern int ixj_init(void);
  119. /*
  120.  *    Initialise Telephony for linux
  121.  */
  122. int telephony_init(void)
  123. {
  124. printk(KERN_INFO "Linux telephony interface: v1.00n");
  125. if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
  126. printk("phonedev: unable to get major %dn", PHONE_MAJOR);
  127. return -EIO;
  128. }
  129. /*
  130.  *    Init kernel installed drivers
  131.  */
  132. #ifdef CONFIG_PHONE_IXJ
  133. ixj_init();  
  134. #endif
  135. return 0;
  136. }
  137. #ifdef MODULE
  138. int init_module(void)
  139. {
  140. return telephony_init();
  141. }
  142. void cleanup_module(void)
  143. {
  144. unregister_chrdev(PHONE_MAJOR, "telephony");
  145. }
  146. #endif
  147. EXPORT_SYMBOL(phone_register_device);
  148. EXPORT_SYMBOL(phone_unregister_device);