pcmciaLib.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* pcmciaLib.c - generic PCMCIA event-handling facilities */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01g,21jun00,rsh  upgrade to dosFs 2.0
  8. 01f,16jan97,hdn  added pCtrl->socks to force a number of sockets.
  9. 01e,08nov96,dgp  doc: final formatting
  10. 01d,28mar96,jdi  doc: cleaned up language and format.
  11. 01c,08mar96,hdn  added more descriptions.
  12. 01b,22feb96,hdn  cleaned up
  13. 01a,05apr95,hdn  written.
  14. */
  15. /*
  16. DESCRIPTION
  17. This library provides generic facilities for handling PCMCIA events.
  18. USER-CALLABLE ROUTINES
  19. Before the driver can be used, it must be initialized by calling pcmciaInit().
  20. This routine should be called exactly once, before any PC card device driver
  21. is used.  Normally, it is called from usrRoot() in usrConfig.c.
  22. The pcmciaInit() routine performs the following actions:
  23. .iP
  24. Creates a message queue.
  25. .iP
  26. Spawns a PCMCIA daemon, which handles jobs in the message queue.
  27. .iP
  28. Finds out which PCMCIA chip is installed and fills out the
  29. PCMCIA_CHIP structure.
  30. .iP
  31. Connects the CSC (Card Status Change) interrupt handler.
  32. .iP
  33. Searches all sockets for a PC card.  If a card is found, it:
  34.     gets CIS (Card Information Structure) information from a card
  35.     determines what type of PC card is in the socket
  36.     allocates a resource for the card if the card is supported
  37.     enables the card
  38. .iP
  39. Enables the CSC interrupt.
  40. .LP
  41. The CSC interrupt handler performs the following actions:
  42. .iP
  43. Searches all sockets for CSC events.
  44. .iP
  45. Calls the PC card's CSC interrupt handler, if there is a PC card in the socket.
  46. .iP
  47. If the CSC event is a hot insertion, it asks the PCMCIA daemon to call cisGet()
  48. at task level.  This call reads the CIS, determines the type of PC card, and
  49. initializes a device driver for the card.
  50. .iP
  51. If the CSC event is a hot removal, it asks the PCMCIA daemon to call cisFree()
  52. at task level.  This call de-allocates resources.
  53. */
  54. /* LINTLIBRARY */
  55. #include "vxWorks.h"
  56. #include "taskLib.h"
  57. #include "msgQLib.h"
  58. #include "intLib.h"
  59. #include "logLib.h"
  60. #include "iv.h"
  61. #include "private/funcBindP.h"
  62. #include "drv/pcmcia/pcmciaLib.h"
  63. #include "drv/pcmcia/cisLib.h"
  64. /* externs */
  65. IMPORT PCMCIA_CTRL pcmciaCtrl;
  66. IMPORT PCMCIA_ADAPTER pcmciaAdapter[];
  67. IMPORT int pcmciaAdapterNumEnt;
  68. IMPORT SEMAPHORE cisMuteSem;
  69. /* globals */
  70. MSG_Q_ID pcmciaMsgQId; /* ID of msgQ to pcmciad */
  71. int pcmciadId; /* pcmciad parameters */
  72. int pcmciadPriority = 2;
  73. int pcmciadOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;
  74. int pcmciadStackSize = 8000;
  75. BOOL pcmciaDebug = FALSE;
  76. /* locals */
  77. LOCAL int pcmciaMsgsLost; /* count of msgs to pcmciad lost */
  78. /* forward declarations */
  79. LOCAL void pcmciaCscIntr (void);
  80. /*******************************************************************************
  81. *
  82. * pcmciaInit - initialize the PCMCIA event-handling package
  83. *
  84. * This routine installs the PCMCIA event-handling facilities and spawns
  85. * pcmciad(), which performs special PCMCIA event-handling functions that
  86. * need to be done at task level.  It also creates the message queue used to
  87. * communicate with pcmciad().
  88. *
  89. * RETURNS:
  90. * OK, or ERROR if a message queue cannot be created or pcmciad() cannot be
  91. * spawned.
  92. *
  93. * SEE ALSO: pcmciad()
  94. */
  95. STATUS pcmciaInit (void)
  96.     {
  97.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  98.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  99.     PCMCIA_CARD *pCard;
  100.     PCMCIA_ADAPTER *pAdapter  = NULL;
  101.     int sock;
  102.     int ix;
  103.     pcmciaMsgQId = msgQCreate (PCMCIA_MAX_MSGS, sizeof(PCMCIA_MSG), MSG_Q_FIFO);
  104.     if (pcmciaMsgQId == NULL)
  105. return (ERROR);
  106.     pcmciadId = taskSpawn ("tPcmciad", pcmciadPriority,
  107.    pcmciadOptions, pcmciadStackSize,
  108.    (FUNCPTR) pcmciad, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  109.     if (pcmciadId == ERROR)
  110. return (ERROR);
  111.     for (ix = 0; ix < pcmciaAdapterNumEnt; ix++)
  112. {
  113.         pAdapter = &pcmciaAdapter[ix];
  114.         if ((* pAdapter->initRtn) (pAdapter->ioBase,
  115.    pAdapter->intVec,
  116.    pAdapter->intLevel,
  117.    pAdapter->showRtn) == OK)
  118.     break;
  119. }
  120.     if (ix >= pcmciaAdapterNumEnt)
  121. return (ERROR);
  122.     semMInit (&cisMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  123.       SEM_INVERSION_SAFE);
  124.     (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(pAdapter->intVec),
  125.        (VOIDFUNCPTR)pcmciaCscIntr, 0);
  126.     if (pCtrl->socks != 0) /* if explicitely defined, use it */
  127.         pChip->socks = pCtrl->socks;
  128.     for (sock = 0; sock < pChip->socks; sock++)
  129. {
  130. pCard = &pCtrl->card[sock];
  131. if ((pCard->cardStatus = (* pChip->status) (sock)) & PC_IS_CARD)
  132.     (void) cisGet (sock);
  133.         (void) (* pChip->cscPoll) (sock);
  134.         (void) (* pChip->cscOn) (sock, pChip->intLevel);
  135. }
  136.     sysIntEnablePIC (pAdapter->intLevel);
  137.     return (OK);
  138.     }
  139. /*******************************************************************************
  140. *
  141. * pcmciaJobAdd - request a task-level function call from interrupt level
  142. *
  143. * This routine allows interrupt level code to request a function call
  144. * to be made by pcmciad at task-level.
  145. *
  146. * NOMANUAL
  147. *
  148. * RETURNS: OK, or ERROR if the message is lost.
  149. */
  150. STATUS pcmciaJobAdd
  151.     (
  152.     VOIDFUNCPTR func, /* function pointer */
  153.     int         arg1, /* argument 1 */
  154.     int         arg2, /* argument 2 */
  155.     int         arg3, /* argument 3 */
  156.     int         arg4, /* argument 4 */
  157.     int         arg5, /* argument 5 */
  158.     int         arg6 /* argument 6 */
  159.     )
  160.     {
  161.     PCMCIA_MSG msg;
  162.     msg.func = func;
  163.     msg.arg[0] = arg1;
  164.     msg.arg[1] = arg2;
  165.     msg.arg[2] = arg3;
  166.     msg.arg[3] = arg4;
  167.     msg.arg[4] = arg5;
  168.     msg.arg[5] = arg6;
  169.     if (msgQSend (pcmciaMsgQId, (char *) &msg, sizeof (msg),
  170.   INT_CONTEXT() ? NO_WAIT : WAIT_FOREVER, MSG_PRI_NORMAL) != OK)
  171.         {
  172.         ++pcmciaMsgsLost;
  173.         return (ERROR);
  174.         }
  175.     return (OK);
  176.     }
  177. /*******************************************************************************
  178. *
  179. * pcmciad - handle task-level PCMCIA events
  180. *
  181. * This routine is spawned as a task by pcmciaInit() to perform functions
  182. * that cannot be performed at interrupt or trap level.  It has a priority of 0.
  183. * Do not suspend, delete, or change the priority of this task.
  184. *
  185. * RETURNS: N/A
  186. *
  187. * SEE ALSO: pcmciaInit()
  188. */
  189. void pcmciad (void)
  190.     {
  191.     static int oldMsgsLost = 0;
  192.     int newMsgsLost;
  193.     PCMCIA_MSG msg;
  194.     FOREVER
  195. {
  196. if (msgQReceive (pcmciaMsgQId, (char *) &msg, sizeof (msg),
  197.  WAIT_FOREVER) != sizeof (msg))
  198.     {
  199.     if (_func_logMsg != NULL)
  200.         (* _func_logMsg) ("pcmciad: error receive msg, status = %#xn",
  201.   errno, 0, 0, 0, 0, 0);
  202.     }
  203.         else
  204.             (* msg.func) (msg.arg[0], msg.arg[1], msg.arg[2],
  205.   msg.arg[3], msg.arg[4], msg.arg[5]);
  206. /* check to see if interrupt level lost any more calls */
  207. if ((newMsgsLost = pcmciaMsgsLost) != oldMsgsLost)
  208.     {
  209.     if (_func_logMsg != NULL)
  210.         (* _func_logMsg) ("%d messages from interrupt level lost.n",
  211.   newMsgsLost - oldMsgsLost, 0, 0, 0, 0, 0);
  212.     oldMsgsLost = newMsgsLost;
  213.     }
  214. }
  215.     }
  216. /*******************************************************************************
  217. *
  218. * pcmciaCscIntr - interrupt handler for card status change
  219. *
  220. * This routine is interrupt handler for card status change.
  221. *
  222. * RETURNS: N/A
  223. */
  224. LOCAL void pcmciaCscIntr (void)
  225.     {
  226.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  227.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  228.     PCMCIA_CARD *pCard;
  229.     int sock;
  230.     int csc;
  231.     int status;
  232.     for (sock = 0; sock < pChip->socks; sock++)
  233. {
  234. pCard = &pCtrl->card[sock];
  235. /* get changed status bits */
  236. if ((csc = (* pChip->cscPoll) (sock)) != 0)
  237.     status = (* pChip->status) (sock);
  238. else
  239.     continue;
  240. /* ignore if the status doesn't change */
  241. if (status ^ pCard->cardStatus)
  242.     pCard->cardStatus = status;
  243. else
  244.     continue;
  245. if ((pcmciaDebug) && (_func_logMsg != NULL))
  246.     (* _func_logMsg) ("CSC sock=%d csc=0x%-4x status=0x%-4xn",
  247.       sock, csc, pCard->cardStatus, 0, 0, 0);
  248. /* card's CSC interrupt handler. go next sock if it returns ERROR */
  249. if (pCard->cscIntr != NULL)
  250.     if ((* pCard->cscIntr) (sock, csc) != OK)
  251. continue;
  252. /* hot insertion */
  253. if ((csc & PC_DETECT) && (pCard->cardStatus & PC_IS_CARD))
  254.     {
  255.     pcmciaJobAdd ((VOIDFUNCPTR)cisGet, sock, 0,0,0,0,0);
  256.     if ((pcmciaDebug) && (_func_logMsg != NULL))
  257.         (* _func_logMsg) ("Inserted: pcmciaJobAdd (cisGet)n",
  258.   0, 0, 0, 0, 0, 0);
  259.     }
  260. /* hot removal */
  261. if ((csc & PC_DETECT) && (pCard->cardStatus & PC_NO_CARD))
  262.     {
  263.     pcmciaJobAdd (cisFree, sock, 0,0,0,0,0);
  264.     if ((pcmciaDebug) && (_func_logMsg != NULL))
  265.         (* _func_logMsg) ("Removed: pcmciaJobAdd (cisFree)n",
  266.   0, 0, 0, 0, 0, 0);
  267.     }
  268. }
  269.     }