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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Generic PCI pccard driver interface.
  3.  *
  4.  * (C) Copyright 1999 Linus Torvalds
  5.  *
  6.  * This implements the common parts of PCI pccard drivers,
  7.  * notably detection and infrastructure conversion (ie change
  8.  * from socket index to "struct pci_dev" etc)
  9.  *
  10.  * This does NOT implement the actual low-level driver details,
  11.  * and this has on purpose been left generic enough that it can
  12.  * be used to set up a PCI PCMCIA controller (ie non-cardbus),
  13.  * or to set up a controller.
  14.  *
  15.  * See for example the "yenta" driver for PCI cardbus controllers
  16.  * conforming to the yenta cardbus specifications.
  17.  */
  18. #include <linux/module.h>
  19. #include <linux/init.h>
  20. #include <linux/pci.h>
  21. #include <linux/sched.h>
  22. #include <linux/interrupt.h>
  23. #include <pcmcia/ss.h>
  24. #include <asm/io.h>
  25. #include "pci_socket.h"
  26. extern struct socket_info_t *pcmcia_register_socket (int slot,
  27. struct pccard_operations *vtable, int use_bus_pm);
  28. extern void pcmcia_unregister_socket (struct socket_info_t *socket);
  29. extern void pcmcia_suspend_socket (struct socket_info_t *socket);
  30. extern void pcmcia_resume_socket (struct socket_info_t *socket);
  31. /*
  32.  * Arbitrary define. This is the array of active cardbus
  33.  * entries.
  34.  */
  35. #define MAX_SOCKETS (8)
  36. static pci_socket_t pci_socket_array[MAX_SOCKETS];
  37. static int pci_init_socket(unsigned int sock)
  38. {
  39. pci_socket_t *socket = pci_socket_array + sock;
  40. if (socket->op && socket->op->init)
  41. return socket->op->init(socket);
  42. return -EINVAL;
  43. }
  44. static int pci_suspend_socket(unsigned int sock)
  45. {
  46. pci_socket_t *socket = pci_socket_array + sock;
  47. if (socket->op && socket->op->suspend)
  48. return socket->op->suspend(socket);
  49. return -EINVAL;
  50. }
  51. static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
  52. {
  53. pci_socket_t *socket = pci_socket_array + sock;
  54. socket->handler = handler;
  55. socket->info = info;
  56. if (handler)
  57. MOD_INC_USE_COUNT;
  58. else
  59. MOD_DEC_USE_COUNT;
  60. return 0;
  61. }
  62. static int pci_inquire_socket(unsigned int sock, socket_cap_t *cap)
  63. {
  64. pci_socket_t *socket = pci_socket_array + sock;
  65. *cap = socket->cap;
  66. return 0;
  67. }
  68. static int pci_get_status(unsigned int sock, unsigned int *value)
  69. {
  70. pci_socket_t *socket = pci_socket_array + sock;
  71. if (socket->op && socket->op->get_status)
  72. return socket->op->get_status(socket, value);
  73. *value = 0;
  74. return -EINVAL;
  75. }
  76. static int pci_get_socket(unsigned int sock, socket_state_t *state)
  77. {
  78. pci_socket_t *socket = pci_socket_array + sock;
  79. if (socket->op && socket->op->get_socket)
  80. return socket->op->get_socket(socket, state);
  81. return -EINVAL;
  82. }
  83. static int pci_set_socket(unsigned int sock, socket_state_t *state)
  84. {
  85. pci_socket_t *socket = pci_socket_array + sock;
  86. if (socket->op && socket->op->set_socket)
  87. return socket->op->set_socket(socket, state);
  88. return -EINVAL;
  89. }
  90. static int pci_get_io_map(unsigned int sock, struct pccard_io_map *io)
  91. {
  92. pci_socket_t *socket = pci_socket_array + sock;
  93. if (socket->op && socket->op->get_io_map)
  94. return socket->op->get_io_map(socket, io);
  95. return -EINVAL;
  96. }
  97. static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
  98. {
  99. pci_socket_t *socket = pci_socket_array + sock;
  100. if (socket->op && socket->op->set_io_map)
  101. return socket->op->set_io_map(socket, io);
  102. return -EINVAL;
  103. }
  104. static int pci_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
  105. {
  106. pci_socket_t *socket = pci_socket_array + sock;
  107. if (socket->op && socket->op->get_mem_map)
  108. return socket->op->get_mem_map(socket, mem);
  109. return -EINVAL;
  110. }
  111. static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
  112. {
  113. pci_socket_t *socket = pci_socket_array + sock;
  114. if (socket->op && socket->op->set_mem_map)
  115. return socket->op->set_mem_map(socket, mem);
  116. return -EINVAL;
  117. }
  118. static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base)
  119. {
  120. pci_socket_t *socket = pci_socket_array + sock;
  121. if (socket->op && socket->op->proc_setup)
  122. socket->op->proc_setup(socket, base);
  123. }
  124. static struct pccard_operations pci_socket_operations = {
  125. pci_init_socket,
  126. pci_suspend_socket,
  127. pci_register_callback,
  128. pci_inquire_socket,
  129. pci_get_status,
  130. pci_get_socket,
  131. pci_set_socket,
  132. pci_get_io_map,
  133. pci_set_io_map,
  134. pci_get_mem_map,
  135. pci_set_mem_map,
  136. pci_proc_setup
  137. };
  138. static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
  139. {
  140. pci_socket_t *socket = nr + pci_socket_array;
  141. int err;
  142. memset(socket, 0, sizeof(*socket));
  143. socket->dev = dev;
  144. socket->op = ops;
  145. pci_set_drvdata(dev, socket);
  146. spin_lock_init(&socket->event_lock);
  147. err = socket->op->open(socket);
  148. if(err)
  149. {
  150. socket->dev = NULL;
  151. pci_set_drvdata(dev, NULL);
  152. }
  153. return err;
  154. }
  155. void cardbus_register(pci_socket_t *socket)
  156. {
  157. int nr = socket - pci_socket_array;
  158. socket->pcmcia_socket = pcmcia_register_socket(nr, &pci_socket_operations, 1);
  159. }
  160. static int __devinit
  161. cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id)
  162. {
  163. int s;
  164. for (s = 0; s < MAX_SOCKETS; s++) {
  165. if (pci_socket_array [s].dev == 0) {
  166. return add_pci_socket (s, dev, &yenta_operations);
  167. }
  168. }
  169. return -ENODEV;
  170. }
  171. static void __devexit cardbus_remove (struct pci_dev *dev)
  172. {
  173. pci_socket_t *socket = pci_get_drvdata(dev);
  174. pcmcia_unregister_socket (socket->pcmcia_socket);
  175. if (socket->op && socket->op->close)
  176. socket->op->close(socket);
  177. pci_set_drvdata(dev, NULL);
  178. }
  179. static int cardbus_suspend (struct pci_dev *dev, u32 state)
  180. {
  181. pci_socket_t *socket = pci_get_drvdata(dev);
  182. pcmcia_suspend_socket (socket->pcmcia_socket);
  183. return 0;
  184. }
  185. static int cardbus_resume (struct pci_dev *dev)
  186. {
  187. pci_socket_t *socket = pci_get_drvdata(dev);
  188. pcmcia_resume_socket (socket->pcmcia_socket);
  189. return 0;
  190. }
  191. static struct pci_device_id cardbus_table [] __devinitdata = { {
  192. class: PCI_CLASS_BRIDGE_CARDBUS << 8,
  193. class_mask: ~0,
  194. vendor: PCI_ANY_ID,
  195. device: PCI_ANY_ID,
  196. subvendor: PCI_ANY_ID,
  197. subdevice: PCI_ANY_ID,
  198. }, { /* all zeroes */ }
  199. };
  200. MODULE_DEVICE_TABLE(pci, cardbus_table);
  201. static struct pci_driver pci_cardbus_driver = {
  202. name: "cardbus",
  203. id_table: cardbus_table,
  204. probe: cardbus_probe,
  205. remove: __devexit_p(cardbus_remove),
  206. suspend: cardbus_suspend,
  207. resume: cardbus_resume,
  208. };
  209. static int __init pci_socket_init(void)
  210. {
  211. return pci_module_init (&pci_cardbus_driver);
  212. }
  213. static void __exit pci_socket_exit (void)
  214. {
  215. pci_unregister_driver (&pci_cardbus_driver);
  216. }
  217. module_init(pci_socket_init);
  218. module_exit(pci_socket_exit);