adummy.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * adummy.c: a dummy ATM driver
  3. */
  4. #include <linux/config.h>
  5. #include <linux/module.h>
  6. #include <linux/version.h>
  7. #include <linux/kernel.h>
  8. #include <linux/skbuff.h>
  9. #include <linux/pci.h>
  10. #include <linux/errno.h>
  11. #include <linux/types.h>
  12. #include <linux/string.h>
  13. #include <linux/delay.h>
  14. #include <linux/init.h>
  15. #include <linux/mm.h>
  16. #include <linux/sched.h>
  17. #include <linux/timer.h>
  18. #include <linux/interrupt.h>
  19. #include <asm/io.h>
  20. #include <asm/byteorder.h>
  21. #include <asm/uaccess.h>
  22. #include <linux/atmdev.h>
  23. #include <linux/atm.h>
  24. #include <linux/sonet.h>
  25. /* version definition */
  26. #define DRV_VERSION "1.0"
  27. #define DEV_LABEL "adummy"
  28. #define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
  29. struct adummy_dev {
  30. struct atm_dev *atm_dev;
  31. struct list_head entry;
  32. };
  33. /* globals */
  34. static LIST_HEAD(adummy_devs);
  35. static int __init
  36. adummy_start(struct atm_dev *dev)
  37. {
  38. dev->ci_range.vpi_bits = 4;
  39. dev->ci_range.vci_bits = 12;
  40. return 0;
  41. }
  42. static int
  43. adummy_open(struct atm_vcc *vcc)
  44. {
  45. short vpi = vcc->vpi;
  46. int vci = vcc->vci;
  47. if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
  48. return 0;
  49. set_bit(ATM_VF_ADDR, &vcc->flags);
  50. set_bit(ATM_VF_READY, &vcc->flags);
  51. return 0;
  52. }
  53. static void
  54. adummy_close(struct atm_vcc *vcc)
  55. {
  56. clear_bit(ATM_VF_READY, &vcc->flags);
  57. clear_bit(ATM_VF_ADDR, &vcc->flags);
  58. }
  59. static int
  60. adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
  61. {
  62. if (vcc->pop)
  63. vcc->pop(vcc, skb);
  64. else
  65. dev_kfree_skb_any(skb);
  66. atomic_inc(&vcc->stats->tx);
  67. return 0;
  68. }
  69. static int
  70. adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
  71. {
  72. int left = *pos;
  73. if (!left--)
  74. return sprintf(page, "version %s\n", DRV_VERSION);
  75. return 0;
  76. }
  77. static struct atmdev_ops adummy_ops =
  78. {
  79. .open = adummy_open,
  80. .close = adummy_close,
  81. .send = adummy_send,
  82. .proc_read = adummy_proc_read,
  83. .owner = THIS_MODULE
  84. };
  85. static int __init adummy_init(void)
  86. {
  87. struct atm_dev *atm_dev;
  88. struct adummy_dev *adummy_dev;
  89. int err = 0;
  90. printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
  91. adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev),
  92. GFP_KERNEL);
  93. if (!adummy_dev) {
  94. printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n");
  95. err = -ENOMEM;
  96. goto out;
  97. }
  98. memset(adummy_dev, 0, sizeof(struct adummy_dev));
  99. atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
  100. if (!atm_dev) {
  101. printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
  102. err = -ENODEV;
  103. goto out_kfree;
  104. }
  105. adummy_dev->atm_dev = atm_dev;
  106. atm_dev->dev_data = adummy_dev;
  107. if (adummy_start(atm_dev)) {
  108. printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
  109. err = -ENODEV;
  110. goto out_unregister;
  111. }
  112. list_add(&adummy_dev->entry, &adummy_devs);
  113. out:
  114. return err;
  115. out_unregister:
  116. atm_dev_deregister(atm_dev);
  117. out_kfree:
  118. kfree(adummy_dev);
  119. goto out;
  120. }
  121. static void __exit adummy_cleanup(void)
  122. {
  123. struct adummy_dev *adummy_dev, *next;
  124. list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
  125. atm_dev_deregister(adummy_dev->atm_dev);
  126. kfree(adummy_dev);
  127. }
  128. }
  129. module_init(adummy_init);
  130. module_exit(adummy_cleanup);
  131. MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
  132. MODULE_DESCRIPTION("dummy ATM driver");
  133. MODULE_LICENSE("GPL");