resources.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* net/atm/resources.c - Staticly allocated resources */
  2. /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  3. #include <linux/config.h>
  4. #include <linux/ctype.h>
  5. #include <linux/string.h>
  6. #include <linux/atmdev.h>
  7. #include <linux/kernel.h> /* for barrier */
  8. #include <linux/module.h>
  9. #include <linux/bitops.h>
  10. #include <net/sock.h>  /* for struct sock */
  11. #include <asm/segment.h> /* for get_fs_long and put_fs_long */
  12. #include "common.h"
  13. #include "resources.h"
  14. #ifndef NULL
  15. #define NULL 0
  16. #endif
  17. struct atm_dev *atm_devs = NULL;
  18. static struct atm_dev *last_dev = NULL;
  19. struct atm_vcc *nodev_vccs = NULL;
  20. extern spinlock_t atm_dev_lock;
  21. static struct atm_dev *alloc_atm_dev(const char *type)
  22. {
  23. struct atm_dev *dev;
  24. dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
  25. if (!dev) return NULL;
  26. memset(dev,0,sizeof(*dev));
  27. dev->type = type;
  28. dev->signal = ATM_PHY_SIG_UNKNOWN;
  29. dev->link_rate = ATM_OC3_PCR;
  30. dev->next = NULL;
  31. dev->prev = last_dev;
  32. if (atm_devs) last_dev->next = dev;
  33. else atm_devs = dev;
  34. last_dev = dev;
  35. return dev;
  36. }
  37. static void free_atm_dev(struct atm_dev *dev)
  38. {
  39. if (dev->prev) dev->prev->next = dev->next;
  40. else atm_devs = dev->next;
  41. if (dev->next) dev->next->prev = dev->prev;
  42. else last_dev = dev->prev;
  43. kfree(dev);
  44. }
  45. struct atm_dev *atm_find_dev(int number)
  46. {
  47. struct atm_dev *dev;
  48. for (dev = atm_devs; dev; dev = dev->next)
  49. if (dev->ops && dev->number == number) return dev;
  50. return NULL;
  51. }
  52. struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
  53.     int number,atm_dev_flags_t *flags)
  54. {
  55. struct atm_dev *dev = NULL;
  56. spin_lock(&atm_dev_lock);
  57. dev = alloc_atm_dev(type);
  58. if (!dev) {
  59. printk(KERN_ERR "atm_dev_register: no space for dev %sn",
  60.     type);
  61. goto done;
  62. }
  63. if (number != -1) {
  64. if (atm_find_dev(number)) {
  65. free_atm_dev(dev);
  66. return NULL;
  67. }
  68. dev->number = number;
  69. } else {
  70. dev->number = 0;
  71. while (atm_find_dev(dev->number)) dev->number++;
  72. }
  73. dev->vccs = dev->last = NULL;
  74. dev->dev_data = NULL;
  75. barrier();
  76. dev->ops = ops;
  77. if (flags) 
  78. dev->flags = *flags;
  79. else 
  80. memset(&dev->flags,0,sizeof(dev->flags));
  81. memset((void *) &dev->stats,0,sizeof(dev->stats));
  82. #ifdef CONFIG_PROC_FS
  83. if (ops->proc_read)
  84. if (atm_proc_dev_register(dev) < 0) {
  85. printk(KERN_ERR "atm_dev_register: "
  86.     "atm_proc_dev_register failed for dev %sn",type);
  87. free_atm_dev(dev);
  88. goto done;
  89. }
  90. #endif
  91. done:
  92. spin_unlock(&atm_dev_lock);
  93. return dev;
  94. }
  95. void atm_dev_deregister(struct atm_dev *dev)
  96. {
  97. #ifdef CONFIG_PROC_FS
  98. if (dev->ops->proc_read) atm_proc_dev_deregister(dev);
  99. #endif
  100. spin_lock(&atm_dev_lock);
  101. free_atm_dev(dev);
  102. spin_unlock(&atm_dev_lock);
  103. }
  104. void shutdown_atm_dev(struct atm_dev *dev)
  105. {
  106. if (dev->vccs) {
  107. set_bit(ATM_DF_CLOSE,&dev->flags);
  108. return;
  109. }
  110. if (dev->ops->dev_close) dev->ops->dev_close(dev);
  111. atm_dev_deregister(dev);
  112. }
  113. /* Handler for sk->destruct, invoked by sk_free() */
  114. static void atm_free_sock(struct sock *sk)
  115. {
  116. kfree(sk->protinfo.af_atm);
  117. }
  118. struct sock *alloc_atm_vcc_sk(int family)
  119. {
  120. struct sock *sk;
  121. struct atm_vcc *vcc;
  122. sk = sk_alloc(family, GFP_KERNEL, 1);
  123. if (!sk) return NULL;
  124. vcc = sk->protinfo.af_atm = kmalloc(sizeof(*vcc),GFP_KERNEL);
  125. if (!vcc) {
  126. sk_free(sk);
  127. return NULL;
  128. }
  129. sock_init_data(NULL,sk);
  130. sk->destruct = atm_free_sock;
  131. memset(vcc,0,sizeof(*vcc));
  132. vcc->sk = sk;
  133. if (nodev_vccs) nodev_vccs->prev = vcc;
  134. vcc->prev = NULL;
  135. vcc->next = nodev_vccs;
  136. nodev_vccs = vcc;
  137. return sk;
  138. }
  139. static void unlink_vcc(struct atm_vcc *vcc,struct atm_dev *hold_dev)
  140. {
  141. if (vcc->prev) vcc->prev->next = vcc->next;
  142. else if (vcc->dev) vcc->dev->vccs = vcc->next;
  143.     else nodev_vccs = vcc->next;
  144. if (vcc->next) vcc->next->prev = vcc->prev;
  145. else if (vcc->dev) vcc->dev->last = vcc->prev;
  146. if (vcc->dev && vcc->dev != hold_dev && !vcc->dev->vccs &&
  147.     test_bit(ATM_DF_CLOSE,&vcc->dev->flags))
  148. shutdown_atm_dev(vcc->dev);
  149. }
  150. void free_atm_vcc_sk(struct sock *sk)
  151. {
  152. unlink_vcc(sk->protinfo.af_atm,NULL);
  153. sk_free(sk);
  154. }
  155. void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev)
  156. {
  157. unlink_vcc(vcc,dev);
  158. vcc->dev = dev;
  159. if (dev) {
  160. vcc->next = NULL;
  161. vcc->prev = dev->last;
  162. if (dev->vccs) dev->last->next = vcc;
  163. else dev->vccs = vcc;
  164. dev->last = vcc;
  165. }
  166. else {
  167. if (nodev_vccs) nodev_vccs->prev = vcc;
  168. vcc->next = nodev_vccs;
  169. vcc->prev = NULL;
  170. nodev_vccs = vcc;
  171. }
  172. }
  173. EXPORT_SYMBOL(atm_dev_register);
  174. EXPORT_SYMBOL(atm_dev_deregister);
  175. EXPORT_SYMBOL(atm_find_dev);
  176. EXPORT_SYMBOL(shutdown_atm_dev);
  177. EXPORT_SYMBOL(bind_vcc);