⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcmcialib.c

📁 VXWORKS源代码
💻 C
字号:
/* pcmciaLib.c - generic PCMCIA event-handling facilities *//* Copyright 1984-1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01g,21jun00,rsh  upgrade to dosFs 2.001f,16jan97,hdn  added pCtrl->socks to force a number of sockets.01e,08nov96,dgp  doc: final formatting01d,28mar96,jdi  doc: cleaned up language and format.01c,08mar96,hdn  added more descriptions.01b,22feb96,hdn  cleaned up01a,05apr95,hdn  written.*//*DESCRIPTIONThis library provides generic facilities for handling PCMCIA events.USER-CALLABLE ROUTINESBefore the driver can be used, it must be initialized by calling pcmciaInit().This routine should be called exactly once, before any PC card device driveris used.  Normally, it is called from usrRoot() in usrConfig.c.The pcmciaInit() routine performs the following actions:.iPCreates a message queue..iPSpawns a PCMCIA daemon, which handles jobs in the message queue..iPFinds out which PCMCIA chip is installed and fills out thePCMCIA_CHIP structure..iPConnects the CSC (Card Status Change) interrupt handler..iPSearches all sockets for a PC card.  If a card is found, it:    gets CIS (Card Information Structure) information from a card    determines what type of PC card is in the socket    allocates a resource for the card if the card is supported    enables the card.iPEnables the CSC interrupt..LPThe CSC interrupt handler performs the following actions:.iPSearches all sockets for CSC events..iPCalls the PC card's CSC interrupt handler, if there is a PC card in the socket..iPIf the CSC event is a hot insertion, it asks the PCMCIA daemon to call cisGet()at task level.  This call reads the CIS, determines the type of PC card, andinitializes a device driver for the card..iPIf the CSC event is a hot removal, it asks the PCMCIA daemon to call cisFree()at task level.  This call de-allocates resources.*//* LINTLIBRARY */#include "vxWorks.h"#include "taskLib.h"#include "msgQLib.h"#include "intLib.h"#include "logLib.h"#include "iv.h"#include "private/funcBindP.h"#include "drv/pcmcia/pcmciaLib.h"#include "drv/pcmcia/cisLib.h"/* externs */IMPORT PCMCIA_CTRL	pcmciaCtrl;IMPORT PCMCIA_ADAPTER	pcmciaAdapter[];IMPORT int		pcmciaAdapterNumEnt;IMPORT SEMAPHORE	cisMuteSem;/* globals */MSG_Q_ID	pcmciaMsgQId;		/* ID of msgQ to pcmciad */int		pcmciadId;		/* pcmciad parameters */int		pcmciadPriority		= 2;int		pcmciadOptions		= VX_SUPERVISOR_MODE | VX_UNBREAKABLE;int		pcmciadStackSize	= 8000;BOOL		pcmciaDebug		= FALSE;/* locals */LOCAL int	pcmciaMsgsLost;		/* count of msgs to pcmciad lost *//* forward declarations */LOCAL void	pcmciaCscIntr	(void);/********************************************************************************* pcmciaInit - initialize the PCMCIA event-handling package** This routine installs the PCMCIA event-handling facilities and spawns* pcmciad(), which performs special PCMCIA event-handling functions that* need to be done at task level.  It also creates the message queue used to* communicate with pcmciad().** RETURNS:* OK, or ERROR if a message queue cannot be created or pcmciad() cannot be* spawned.** SEE ALSO: pcmciad()*/STATUS pcmciaInit (void)    {    PCMCIA_CTRL *pCtrl		= &pcmciaCtrl;    PCMCIA_CHIP *pChip		= &pCtrl->chip;    PCMCIA_CARD *pCard;    PCMCIA_ADAPTER *pAdapter 	= NULL;    int sock;    int ix;    pcmciaMsgQId = msgQCreate (PCMCIA_MAX_MSGS, sizeof(PCMCIA_MSG), MSG_Q_FIFO);    if (pcmciaMsgQId == NULL)	return (ERROR);    pcmciadId = taskSpawn ("tPcmciad", pcmciadPriority,			   pcmciadOptions, pcmciadStackSize,			   (FUNCPTR) pcmciad, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);    if (pcmciadId == ERROR)	return (ERROR);    for (ix = 0; ix < pcmciaAdapterNumEnt; ix++)	{        pAdapter = &pcmciaAdapter[ix];        if ((* pAdapter->initRtn) (pAdapter->ioBase,				   pAdapter->intVec,				   pAdapter->intLevel,				   pAdapter->showRtn) == OK)	    break;	}    if (ix >= pcmciaAdapterNumEnt)	return (ERROR);    semMInit (&cisMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |	      SEM_INVERSION_SAFE);    (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(pAdapter->intVec),		       (VOIDFUNCPTR)pcmciaCscIntr, 0);    if (pCtrl->socks != 0)		/* if explicitely defined, use it */        pChip->socks = pCtrl->socks;    for (sock = 0; sock < pChip->socks; sock++)	{	pCard = &pCtrl->card[sock];	if ((pCard->cardStatus = (* pChip->status) (sock)) & PC_IS_CARD)	    (void) cisGet (sock);        (void) (* pChip->cscPoll) (sock);        (void) (* pChip->cscOn) (sock, pChip->intLevel);	}    sysIntEnablePIC (pAdapter->intLevel);    return (OK);    }/********************************************************************************* pcmciaJobAdd - request a task-level function call from interrupt level** This routine allows interrupt level code to request a function call* to be made by pcmciad at task-level.** NOMANUAL** RETURNS: OK, or ERROR if the message is lost.*/STATUS pcmciaJobAdd    (    VOIDFUNCPTR func,		/* function pointer */    int         arg1,		/* argument 1 */    int         arg2,		/* argument 2 */    int         arg3,		/* argument 3 */    int         arg4,		/* argument 4 */    int         arg5,		/* argument 5 */    int         arg6		/* argument 6 */    )    {    PCMCIA_MSG msg;    msg.func	= func;    msg.arg[0]	= arg1;    msg.arg[1]	= arg2;    msg.arg[2]	= arg3;    msg.arg[3]	= arg4;    msg.arg[4]	= arg5;    msg.arg[5]	= arg6;    if (msgQSend (pcmciaMsgQId, (char *) &msg, sizeof (msg),		  INT_CONTEXT() ? NO_WAIT : WAIT_FOREVER, MSG_PRI_NORMAL) != OK)        {        ++pcmciaMsgsLost;        return (ERROR);        }    return (OK);    }/********************************************************************************* pcmciad - handle task-level PCMCIA events** This routine is spawned as a task by pcmciaInit() to perform functions* that cannot be performed at interrupt or trap level.  It has a priority of 0.* Do not suspend, delete, or change the priority of this task.** RETURNS: N/A** SEE ALSO: pcmciaInit()*/void pcmciad (void)    {    static int oldMsgsLost = 0;    int newMsgsLost;    PCMCIA_MSG msg;    FOREVER	{	if (msgQReceive (pcmciaMsgQId, (char *) &msg, sizeof (msg),			 WAIT_FOREVER) != sizeof (msg))	    {	    if (_func_logMsg != NULL)	        (* _func_logMsg) ("pcmciad: error receive msg, status = %#x\n",				  errno, 0, 0, 0, 0, 0);	    }        else            (* msg.func) (msg.arg[0], msg.arg[1], msg.arg[2],			  msg.arg[3], msg.arg[4], msg.arg[5]);	/* check to see if interrupt level lost any more calls */	if ((newMsgsLost = pcmciaMsgsLost) != oldMsgsLost)	    {	    if (_func_logMsg != NULL)	        (* _func_logMsg) ("%d messages from interrupt level lost.\n",				  newMsgsLost - oldMsgsLost, 0, 0, 0, 0, 0);	    oldMsgsLost = newMsgsLost;	    }	}    }/********************************************************************************* pcmciaCscIntr - interrupt handler for card status change** This routine is interrupt handler for card status change.** RETURNS: N/A*/LOCAL void pcmciaCscIntr (void)    {    PCMCIA_CTRL *pCtrl = &pcmciaCtrl;    PCMCIA_CHIP *pChip = &pCtrl->chip;    PCMCIA_CARD *pCard;    int sock;    int csc;    int status;    for (sock = 0; sock < pChip->socks; sock++)	{	pCard = &pCtrl->card[sock];	/* get changed status bits */	if ((csc = (* pChip->cscPoll) (sock)) != 0)	    status = (* pChip->status) (sock);	else	    continue;	/* ignore if the status doesn't change */	if (status ^ pCard->cardStatus)	    pCard->cardStatus = status;	else	    continue;	if ((pcmciaDebug) && (_func_logMsg != NULL))	    (* _func_logMsg) ("CSC sock=%d csc=0x%-4x status=0x%-4x\n",			      sock, csc, pCard->cardStatus, 0, 0, 0);	/* card's CSC interrupt handler. go next sock if it returns ERROR */	if (pCard->cscIntr != NULL)	    if ((* pCard->cscIntr) (sock, csc) != OK)		continue;	/* hot insertion */	if ((csc & PC_DETECT) && (pCard->cardStatus & PC_IS_CARD))	    {	    pcmciaJobAdd ((VOIDFUNCPTR)cisGet, sock, 0,0,0,0,0);	    if ((pcmciaDebug) && (_func_logMsg != NULL))	        (* _func_logMsg) ("Inserted: pcmciaJobAdd (cisGet)\n",				  0, 0, 0, 0, 0, 0);	    }	/* hot removal */	if ((csc & PC_DETECT) && (pCard->cardStatus & PC_NO_CARD))	    {	    pcmciaJobAdd (cisFree, sock, 0,0,0,0,0);	    if ((pcmciaDebug) && (_func_logMsg != NULL))	        (* _func_logMsg) ("Removed: pcmciaJobAdd (cisFree)\n",				  0, 0, 0, 0, 0, 0);	    }	}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -