core.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * core.c - contains all core device and protocol registration functions
  3. *
  4. * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
  5. *
  6. */
  7. #include <linux/pnp.h>
  8. #include <linux/types.h>
  9. #include <linux/list.h>
  10. #include <linux/device.h>
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/string.h>
  14. #include <linux/slab.h>
  15. #include <linux/errno.h>
  16. #include <linux/dma-mapping.h>
  17. #include "base.h"
  18. static LIST_HEAD(pnp_protocols);
  19. LIST_HEAD(pnp_global);
  20. DEFINE_SPINLOCK(pnp_lock);
  21. /*
  22. * ACPI or PNPBIOS should tell us about all platform devices, so we can
  23. * skip some blind probes. ISAPNP typically enumerates only plug-in ISA
  24. * devices, not built-in things like COM ports.
  25. */
  26. int pnp_platform_devices;
  27. EXPORT_SYMBOL(pnp_platform_devices);
  28. void *pnp_alloc(long size)
  29. {
  30. void *result;
  31. result = kmalloc(size, GFP_KERNEL);
  32. if (!result){
  33. printk(KERN_ERR "pnp: Out of Memory\n");
  34. return NULL;
  35. }
  36. memset(result, 0, size);
  37. return result;
  38. }
  39. /**
  40. * pnp_protocol_register - adds a pnp protocol to the pnp layer
  41. * @protocol: pointer to the corresponding pnp_protocol structure
  42. *
  43. * Ex protocols: ISAPNP, PNPBIOS, etc
  44. */
  45. int pnp_register_protocol(struct pnp_protocol *protocol)
  46. {
  47. int nodenum;
  48. struct list_head * pos;
  49. if (!protocol)
  50. return -EINVAL;
  51. INIT_LIST_HEAD(&protocol->devices);
  52. INIT_LIST_HEAD(&protocol->cards);
  53. nodenum = 0;
  54. spin_lock(&pnp_lock);
  55. /* assign the lowest unused number */
  56. list_for_each(pos,&pnp_protocols) {
  57. struct pnp_protocol * cur = to_pnp_protocol(pos);
  58. if (cur->number == nodenum){
  59. pos = &pnp_protocols;
  60. nodenum++;
  61. }
  62. }
  63. list_add_tail(&protocol->protocol_list, &pnp_protocols);
  64. spin_unlock(&pnp_lock);
  65. protocol->number = nodenum;
  66. sprintf(protocol->dev.bus_id, "pnp%d", nodenum);
  67. return device_register(&protocol->dev);
  68. }
  69. /**
  70. * pnp_protocol_unregister - removes a pnp protocol from the pnp layer
  71. * @protocol: pointer to the corresponding pnp_protocol structure
  72. *
  73. */
  74. void pnp_unregister_protocol(struct pnp_protocol *protocol)
  75. {
  76. spin_lock(&pnp_lock);
  77. list_del(&protocol->protocol_list);
  78. spin_unlock(&pnp_lock);
  79. device_unregister(&protocol->dev);
  80. }
  81. static void pnp_free_ids(struct pnp_dev *dev)
  82. {
  83. struct pnp_id * id;
  84. struct pnp_id * next;
  85. if (!dev)
  86. return;
  87. id = dev->id;
  88. while (id) {
  89. next = id->next;
  90. kfree(id);
  91. id = next;
  92. }
  93. }
  94. static void pnp_release_device(struct device *dmdev)
  95. {
  96. struct pnp_dev * dev = to_pnp_dev(dmdev);
  97. pnp_free_option(dev->independent);
  98. pnp_free_option(dev->dependent);
  99. pnp_free_ids(dev);
  100. kfree(dev);
  101. }
  102. int __pnp_add_device(struct pnp_dev *dev)
  103. {
  104. int ret;
  105. pnp_fixup_device(dev);
  106. dev->dev.bus = &pnp_bus_type;
  107. dev->dev.dma_mask = &dev->dma_mask;
  108. dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
  109. dev->dev.release = &pnp_release_device;
  110. dev->status = PNP_READY;
  111. spin_lock(&pnp_lock);
  112. list_add_tail(&dev->global_list, &pnp_global);
  113. list_add_tail(&dev->protocol_list, &dev->protocol->devices);
  114. spin_unlock(&pnp_lock);
  115. ret = device_register(&dev->dev);
  116. if (ret == 0)
  117. pnp_interface_attach_device(dev);
  118. return ret;
  119. }
  120. /*
  121. * pnp_add_device - adds a pnp device to the pnp layer
  122. * @dev: pointer to dev to add
  123. *
  124. * adds to driver model, name database, fixups, interface, etc.
  125. */
  126. int pnp_add_device(struct pnp_dev *dev)
  127. {
  128. if (!dev || !dev->protocol || dev->card)
  129. return -EINVAL;
  130. dev->dev.parent = &dev->protocol->dev;
  131. sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, dev->number);
  132. return __pnp_add_device(dev);
  133. }
  134. void __pnp_remove_device(struct pnp_dev *dev)
  135. {
  136. spin_lock(&pnp_lock);
  137. list_del(&dev->global_list);
  138. list_del(&dev->protocol_list);
  139. spin_unlock(&pnp_lock);
  140. device_unregister(&dev->dev);
  141. }
  142. /**
  143. * pnp_remove_device - removes a pnp device from the pnp layer
  144. * @dev: pointer to dev to add
  145. *
  146. * this function will free all mem used by dev
  147. */
  148. #if 0
  149. void pnp_remove_device(struct pnp_dev *dev)
  150. {
  151. if (!dev || dev->card)
  152. return;
  153. __pnp_remove_device(dev);
  154. }
  155. #endif /* 0 */
  156. static int __init pnp_init(void)
  157. {
  158. printk(KERN_INFO "Linux Plug and Play Support v0.97 (c) Adam Belay\n");
  159. return bus_register(&pnp_bus_type);
  160. }
  161. subsys_initcall(pnp_init);
  162. #if 0
  163. EXPORT_SYMBOL(pnp_register_protocol);
  164. EXPORT_SYMBOL(pnp_unregister_protocol);
  165. EXPORT_SYMBOL(pnp_add_device);
  166. EXPORT_SYMBOL(pnp_remove_device);
  167. #endif /* 0 */