resources.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

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_KERNEL);
  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. spin_lock(&atm_dev_lock);
  32. dev->prev = last_dev;
  33. if (atm_devs) last_dev->next = dev;
  34. else atm_devs = dev;
  35. last_dev = dev;
  36. spin_unlock(&atm_dev_lock);
  37. return dev;
  38. }
  39. static void free_atm_dev(struct atm_dev *dev)
  40. {
  41. spin_lock (&atm_dev_lock);
  42. if (dev->prev) dev->prev->next = dev->next;
  43. else atm_devs = dev->next;
  44. if (dev->next) dev->next->prev = dev->prev;
  45. else last_dev = dev->prev;
  46. kfree(dev);
  47. spin_unlock (&atm_dev_lock);
  48. }
  49. struct atm_dev *atm_find_dev(int number)
  50. {
  51. struct atm_dev *dev;
  52. for (dev = atm_devs; dev; dev = dev->next)
  53. if (dev->ops && dev->number == number) return dev;
  54. return NULL;
  55. }
  56. struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
  57.     int number,atm_dev_flags_t *flags)
  58. {
  59. struct atm_dev *dev;
  60. dev = alloc_atm_dev(type);
  61. if (!dev) {
  62. printk(KERN_ERR "atm_dev_register: no space for dev %sn",
  63.     type);
  64. return NULL;
  65. }
  66. if (number != -1) {
  67. if (atm_find_dev(number)) {
  68. free_atm_dev(dev);
  69. return NULL;
  70. }
  71. dev->number = number;
  72. }
  73. else {
  74. dev->number = 0;
  75. while (atm_find_dev(dev->number)) dev->number++;
  76. }
  77. dev->vccs = dev->last = NULL;
  78. dev->dev_data = NULL;
  79. barrier();
  80. dev->ops = ops;
  81. if (flags) dev->flags = *flags;
  82. else memset(&dev->flags,0,sizeof(dev->flags));
  83. memset((void *) &dev->stats,0,sizeof(dev->stats));
  84. #ifdef CONFIG_PROC_FS
  85. if (ops->proc_read)
  86. if (atm_proc_dev_register(dev) < 0) {
  87. printk(KERN_ERR "atm_dev_register: "
  88.     "atm_proc_dev_register failed for dev %sn",type);
  89. spin_unlock (&atm_dev_lock);
  90. free_atm_dev(dev);
  91. return NULL;
  92. }
  93. #endif
  94. spin_unlock (&atm_dev_lock);
  95. return dev;
  96. }
  97. void atm_dev_deregister(struct atm_dev *dev)
  98. {
  99. #ifdef CONFIG_PROC_FS
  100. if (dev->ops->proc_read) atm_proc_dev_deregister(dev);
  101. #endif
  102. free_atm_dev(dev);
  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);