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

📄 cislib.c

📁 用于EQUATOR处理器上的FAT32文件系统(vxWorks5.5)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cisLib.c - PCMCIA CIS library */

/* Copyright 1984-1996 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
01g,17sep98,lrn  reworked DosFs 2.0 support and memory leak issues
01f,14jul98,lrn  DosFs2.0: can not delete DOS devices
01e,16jan97,hdn  added pCtrl->memBase, CIS_MAX_TUPLES.
01d,28mar96,jdi  doc: cleaned up language and format.
01c,08mar96,hdn  added more descriptions.
01b,22feb96,hdn  cleaned up
01a,10feb95,hdn  written.
*/


/*
DESCRIPTION
This library contains routines to manipulate the CIS (Configuration
Information Structure) tuples and the card configuration registers.
The library uses a memory window which is defined in `pcmciaMemwin'
to access the CIS of a PC card.
All CIS tuples in a PC card are read and stored in a linked list,
`cisTupleList'.  If there are configuration tuples, they are interpreted
and stored in another link list, `cisConifigList'.  After the CIS is read,
the PC card's enabler routine allocates resources and initializes a device
driver for the PC card.

If a PC card is inserted, the CSC (Card Status Change) interrupt handler
gets a CSC event from the PCMCIA chip and adds a cisGet() job to the
PCMCIA daemon.  The PCMCIA daemon initiates the cisGet() work.  The CIS
library reads the CIS from the PC card and makes a linked list of CIS
tuples.  It then enables the card.

If the PC card is removed, the CSC interrupt handler gets a CSC event from
the PCMCIA chip and adds a cisFree() job to the PCMCIA daemon.  The PCMCIA
daemon initiates the cisFree() work.  The CIS library frees allocated 
memory for the linked list of CIS tuples.
*/


#include "vxWorks.h"
#include "taskLib.h"
#include "sysLib.h"
#include "stdlib.h"
#include "string.h"
#include "drv/pcmcia/pcmciaLib.h"
#include "drv/pcmcia/cisLib.h"


/* defines */


/* imports */

IMPORT PCMCIA_CTRL	pcmciaCtrl;
IMPORT PCMCIA_MEMWIN	pcmciaMemwin[];
IMPORT PCCARD_ENABLER   pccardEnabler[];
IMPORT int		pccardEnablerNumEnt;


/* globals */

SEMAPHORE	cisMuteSem;


/* locals */

LOCAL u_char	powerMantissa [] = {10, 12, 13, 15, 20, 25, 30, 35,
				 40, 45, 50, 55, 60, 70, 80, 90};
LOCAL u_char	powerExponent [] = {0, 0, 0, 0, 0, 1, 10, 100};


/* forward declarations */

LOCAL STATUS	cisTupleGet	(int sock);
LOCAL STATUS	cisConfigGet	(int sock);
LOCAL STATUS	cisResourceGet	(int sock);


/*******************************************************************************
*
* cisGet - get information from a PC card's CIS
*
* This routine gets information from a PC card's CIS, configures the PC card,
* and allocates resources for the PC card.
*
* RETURNS: OK, or ERROR if it cannot get the CIS information,
* configure the PC card, or allocate resources.
*/

STATUS cisGet
    (
    int sock			/* socket no. */
    )
    {
    PCMCIA_CTRL *pCtrl	= &pcmciaCtrl;
    PCMCIA_CHIP *pChip	= &pCtrl->chip;
    PCMCIA_CARD *pCard	= &pCtrl->card[sock];
    STATUS status	= ERROR;
    DL_NODE *pNode;
    DL_NODE *pTemp;


    semTake (&cisMuteSem, WAIT_FOREVER);	/* mutual exclusion begin */
    (void) (* pChip->cscOff) (sock, pChip->intLevel);

    for (pNode = DLL_FIRST(&pCard->cisTupleList); pNode != NULL; pNode = pTemp)
	{
	pTemp = DLL_NEXT(pNode);
	free (pNode);
	}

    for (pNode = DLL_FIRST(&pCard->cisConfigList); pNode != NULL; pNode = pTemp)
	{
	pTemp = DLL_NEXT(pNode);
	free (pNode);
	}

    dllInit (&pCard->cisTupleList);
    dllInit (&pCard->cisConfigList);

    if ((cisTupleGet (sock) == OK) &&
	(cisConfigGet (sock) == OK) &&
    	(cisResourceGet (sock) == OK))
	status = OK;

    (void) (* pChip->cscPoll) (sock);

    (void) (* pChip->cscOn) (sock, pChip->intLevel);
    semGive (&cisMuteSem);			/* mutual exclusion end */

    return (status);
    }

/*******************************************************************************
*
* cisTupleGet - get tuples from PC card and attach it to the link list
*
* This routine get tuples from PC card and attach it to the link list.
*
* RETURNS: OK, or ERROR if it couldn't set a value to the PCMCIA chip.
*/

LOCAL STATUS cisTupleGet
    (
    int sock			/* socket no. */
    )

    {
    BOOL endList	= FALSE;
    BOOL noLink		= FALSE;
    u_long longlinkA	= 0;
    u_long longlinkC	= 0;
    PCMCIA_CTRL *pCtrl	= &pcmciaCtrl;
    PCMCIA_CHIP *pChip	= &pCtrl->chip;
    PCMCIA_CARD *pCard	= &pCtrl->card[sock];
    int ix		= 0;
    PCMCIA_MEMWIN cisMemwin;
    CIS_TUPLE_A *pTupleA;
    CIS_TUPLE_C *pTupleC;
    DL_NODE *pNode;
    u_char *pChar;
    u_char *pd;
    u_char *ps;
    int flag;
    int tuples;

    /* XXX
     * Assumption
     * 1. CIS tuple chain is in between start and stop in pcmciaMemwin[0].
     * 2. Longlink from Common memory to Attribute memory doesn't occur
     *
     * Card reset/power signal sequence (See p.60 PCMCIA Developer's guide)
     *                  ______________________________________________
     *   Card detect  __|
     *                   >50ms-
     *                         _______________________________________
     *   Vcc          _________|
     *                          >300ms--------
     *   Card signal                          ________________________
     *       enabled  ________________________|
     *                                        __________
     *   Reset        ________________________|        |______________
     *                                         >10ms---
     *                                                  >20ms----
     *   Card access                                             _____
     *       allowed  ___________________________________________|
     */

    if (pChip->installed != TRUE)
	return (ERROR);

    taskDelay (sysClkRateGet() >> 3);		/* 7 * 16ms = 112ms */

    if ((* pChip->reset)(sock) != OK)
	return (ERROR);

    flag = PC_PWR_AUTO | PC_VCC_5V | PC_VPP_5V;
    if ((* pChip->flagSet)(sock, flag) != OK)
	return (ERROR);

    taskDelay (sysClkRateGet() >> 1);		/* 30 * 16ms = 500ms */

    flag = PC_PWR_AUTO | PC_VCC_5V | PC_VPP_5V | PC_RESET;
    if ((* pChip->flagSet)(sock, flag) != OK)
	return (ERROR);

    taskDelay (sysClkRateGet() >> 4);		/* 3 * 16ms = 48ms */

    flag = PC_PWR_AUTO | PC_VCC_5V | PC_VPP_5V;
    if ((* pChip->flagSet)(sock, flag) != OK)
	return (ERROR);

    taskDelay (sysClkRateGet() >> 2);		/* 15 * 16ms = 240ms */

    flag = PC_READY | PC_POWERON;
    while ((((* pChip->status)(sock) & flag) != flag) && (ix++ < 8))
	taskDelay (sysClkRateGet() >> 2);

    do  {

	/* map attribute memory */

	pChar			= (u_char *)pcmciaMemwin[CIS_MEM_TUPLE].start +
				  pCtrl->memBase;
        cisMemwin.window	= PCMCIA_CIS_WINDOW;
        cisMemwin.flags		= MAP_ACTIVE | MAP_16BIT | MAP_ATTRIB;
        cisMemwin.extraws	= 2;
        cisMemwin.start		= pcmciaMemwin[CIS_MEM_TUPLE].start;
        cisMemwin.stop		= pcmciaMemwin[CIS_MEM_TUPLE].stop;
        cisMemwin.cardstart	= longlinkA;
	if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
	    return (ERROR);

	/* check the link target tuple if we had longlink tuple */

	if (longlinkA != 0)
	    {
	    longlinkA = 0;
	    pTupleA = (CIS_TUPLE_A *)pChar;
	    if (pTupleA->code == CISTPL_LINKTARGET)
		pChar += (pTupleA->link + 2) * 2;
	    else
		break;
	    }
	
	/* parse the tuple chain */

	endList = FALSE;
	for (tuples = 0; !endList; tuples++)
	    {
	    pTupleA = (CIS_TUPLE_A *)pChar;

	    switch (pTupleA->code)
		{
		case CISTPL_NULL:
		    pChar += 2;
		    break;
		
		case CISTPL_LONGLINK_A:
		    ps = pChar + 4;
		    pd = (u_char *)&longlinkA;
		    for (ix = 0; ix < 4; ix++)
			*pd++ = *ps++;
		    pChar += (pTupleA->link + 2) * 2;
		    break;
		
		case CISTPL_LONGLINK_C:
		    ps = pChar + 4;
		    pd = (u_char *)&longlinkC;
		    for (ix = 0; ix < 4; ix++)
			*pd++ = *ps++;
		    pChar += (pTupleA->link + 2) * 2;
		    break;
		
		case CISTPL_NO_LINK:
		    noLink = TRUE;
		    pChar += (pTupleA->link + 2) * 2;
		    break;

		case CISTPL_END:
		    if (tuples != 0)
		        endList = TRUE;
		    pChar += (pTupleA->link + 2) * 2;
		    break;

		case CISTPL_CHECKSUM:
		    /* XXX ignore now */
		    pChar += (pTupleA->link + 2) * 2;
		    break;
		
		default:
		    pNode = (DL_NODE *)malloc (pTupleA->link + 2 +
					       sizeof(DL_NODE));
		    pd = (u_char *)pNode + sizeof(DL_NODE);
		    ps = pChar;
		    for (ix = 0; ix < (pTupleA->link + 2); ix++)
			{
			*pd++ = *ps++;
			ps++;
			}
		    dllAdd (&pCard->cisTupleList, pNode);
		    pChar += (pTupleA->link + 2) * 2;
		    break;
		}
	    if ((pTupleA->link == 0xff) || (tuples >= CIS_MAX_TUPLES))
		endList = TRUE;
	    }
	} while (longlinkA != 0);

    if (noLink)
	{
        /* unmap memory window */

        cisMemwin.window	= 0;
        cisMemwin.flags		= 0;
        cisMemwin.extraws	= 0;
        cisMemwin.start		= 0;
        cisMemwin.stop		= 0;
        cisMemwin.cardstart	= 0;
        if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
            return (ERROR);
        return (OK);
	}


    do  {

	/* map common memory */

	pChar			= (u_char *)pcmciaMemwin[CIS_MEM_TUPLE].start +
				  pCtrl->memBase;
        cisMemwin.window	= PCMCIA_CIS_WINDOW;
        cisMemwin.flags		= MAP_ACTIVE | MAP_16BIT;
        cisMemwin.extraws	= 2;
        cisMemwin.start		= pcmciaMemwin[CIS_MEM_TUPLE].start;
        cisMemwin.stop		= pcmciaMemwin[CIS_MEM_TUPLE].stop;
        cisMemwin.cardstart	= longlinkC;
	if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
	    return (ERROR);

	/* check the link target tuple */

	pTupleC = (CIS_TUPLE_C *)pChar;
	if (pTupleC->code == CISTPL_LINKTARGET)
	    pChar += pTupleC->link + 2;
	else
	    break;

	/* parse the tuple chain */

	endList = FALSE;
	for (tuples = 0; !endList; tuples++)
	    {
	    pTupleC = (CIS_TUPLE_C *)pChar;
	    switch (pTupleC->code)
		{
		case CISTPL_NULL:
		    pChar++;
		    break;

		case CISTPL_LONGLINK_A:
		    ps = pChar + 2;
		    pd = (u_char *)&longlinkA;
		    for (ix = 0; ix < 4; ix++)
			*pd++ = *ps++;
		    
		    pChar += pTupleC->link + 2;
		    break;

		case CISTPL_LONGLINK_C:
		    ps = pChar + 2;
		    pd = (u_char *)&longlinkC;
		    for (ix = 0; ix < 4; ix++)
			*pd++ = *ps++;
		    
		    pChar += pTupleC->link + 2;
		    break;
		
		case CISTPL_NO_LINK:
		    noLink = TRUE;
		    pChar += pTupleC->link + 2;
		    break;
		
		case CISTPL_END:
		    if (tuples != 0)
		        endList = TRUE;
		    pChar += pTupleC->link + 2;
		    break;

		case CISTPL_CHECKSUM:
		    /* XXX ignore now */
		    pChar += pTupleC->link + 2;
		    break;
		
		default:
		    pNode = (DL_NODE *)malloc (pTupleC->link + 2 + 
					       sizeof(DL_NODE));
		    pd = (u_char *)pNode + sizeof(DL_NODE);
		    ps = pChar;
		    for (ix = 0; ix < (pTupleC->link + 2); ix++)
			*pd++ = *ps++;
		    dllAdd (&pCard->cisTupleList, pNode);
		    pChar += pTupleC->link + 2;
		    break;
		}
	    if ((pTupleC->link == 0xff) || (tuples >= CIS_MAX_TUPLES))
		endList = TRUE;
	    }
	} while (longlinkC != 0);

    /* unmap memory window */

    cisMemwin.window		= 0;
    cisMemwin.flags		= 0;
    cisMemwin.extraws		= 0;
    cisMemwin.start		= 0;
    cisMemwin.stop		= 0;
    cisMemwin.cardstart		= 0;
    if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
        return (ERROR);

    return (OK);
    }

/*******************************************************************************
*
* cisConfigGet - get configuration information from the CIS tuple link list
*
* Get configuration information from the CIS tuple link list.
*
* RETURNS: OK (always).
*/

LOCAL STATUS cisConfigGet
    (
    int sock			/* socket no. */
    )

    {
    PCMCIA_CTRL *pCtrl		= &pcmciaCtrl;
    PCMCIA_CARD *pCard		= &pCtrl->card[sock];
    CIS_CONFIG *pDefault	= 0;
    CIS_CONFIG *pConfig;
    DL_NODE *pNode;
    CIS_TUPLE *pTuple;
    CIS_BYTE4 base;
    CIS_BYTE4 mask;
    CIS_BYTE4 addr;
    CIS_BYTE4 length;
    CIS_BYTE4 cAddr;
    CIS_BYTE4 hAddr;
    int lengthSize;
    int addrSize;
    int maskSize;
    int windows;
    int ix;
    u_char *pChar;
    u_char *pEnd;
    u_char *pv;
    u_char featureSelection;
    u_char parameterSelection;
    u_char hostaddr;
    u_char waitScale;
    u_char busyScale;
    u_char reservedScale;


    for (pNode = DLL_FIRST (&pCard->cisTupleList);
	 pNode != NULL;
	 pNode = DLL_NEXT(pNode))
	{
	pTuple	= (CIS_TUPLE *)((char *)pNode + sizeof (DL_NODE));
	pChar	= (u_char *)pTuple + sizeof (CIS_TUPLE);
	pEnd	= pChar + pTuple->link;

	switch (pTuple->code)
	    {
	    case CISTPL_CONFIG:
		pCard->regBase = 0;
		pCard->regMask = 0;
		addrSize = (*pChar & 0x03) + 1;
		maskSize = ((*pChar & 0x3c) >> 2) + 1;
		pChar += 2;
		if (pChar > pEnd)
		    break;

		base.l = 0;
		for (ix = 0; ix < addrSize; ix++)
		    base.c[ix] = *pChar++;

		mask.l = 0;
		for (ix = 0; ix < maskSize; ix++)
		    mask.c[ix] = *pChar++;
		
		pCard->regBase = base.l;
		pCard->regMask = mask.l;
		break;
	    
	    case CISTPL_CFTABLE_ENTRY:
		pConfig = (CIS_CONFIG *)calloc(1, sizeof(CIS_CONFIG));
		if (*pChar & 0x40)
		    pDefault = pConfig;
		else if (pDefault != 0)
		    {
		    bcopy ((char *)pDefault, (char *)pConfig, 
			   sizeof(CIS_CONFIG));

⌨️ 快捷键说明

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