cisLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:25k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* cisLib.c - PCMCIA CIS library */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,21jun00,rsh  upgrade to dosFs 2.0
  8. 01g,17sep98,lrn  reworked DosFs 2.0 support and memory leak issues
  9. 01f,14jul98,lrn  DosFs2.0: can not delete DOS devices
  10. 01e,16jan97,hdn  added pCtrl->memBase, CIS_MAX_TUPLES.
  11. 01d,28mar96,jdi  doc: cleaned up language and format.
  12. 01c,08mar96,hdn  added more descriptions.
  13. 01b,22feb96,hdn  cleaned up
  14. 01a,10feb95,hdn  written.
  15. */
  16. /*
  17. DESCRIPTION
  18. This library contains routines to manipulate the CIS (Configuration
  19. Information Structure) tuples and the card configuration registers.
  20. The library uses a memory window which is defined in `pcmciaMemwin'
  21. to access the CIS of a PC card.
  22. All CIS tuples in a PC card are read and stored in a linked list,
  23. `cisTupleList'.  If there are configuration tuples, they are interpreted
  24. and stored in another link list, `cisConifigList'.  After the CIS is read,
  25. the PC card's enabler routine allocates resources and initializes a device
  26. driver for the PC card.
  27. If a PC card is inserted, the CSC (Card Status Change) interrupt handler
  28. gets a CSC event from the PCMCIA chip and adds a cisGet() job to the
  29. PCMCIA daemon.  The PCMCIA daemon initiates the cisGet() work.  The CIS
  30. library reads the CIS from the PC card and makes a linked list of CIS
  31. tuples.  It then enables the card.
  32. If the PC card is removed, the CSC interrupt handler gets a CSC event from
  33. the PCMCIA chip and adds a cisFree() job to the PCMCIA daemon.  The PCMCIA
  34. daemon initiates the cisFree() work.  The CIS library frees allocated 
  35. memory for the linked list of CIS tuples.
  36. */
  37. #include "vxWorks.h"
  38. #include "taskLib.h"
  39. #include "sysLib.h"
  40. #include "stdlib.h"
  41. #include "string.h"
  42. #include "drv/pcmcia/pcmciaLib.h"
  43. #include "drv/pcmcia/cisLib.h"
  44. /* defines */
  45. /* imports */
  46. IMPORT PCMCIA_CTRL pcmciaCtrl;
  47. IMPORT PCMCIA_MEMWIN pcmciaMemwin[];
  48. IMPORT PCCARD_ENABLER   pccardEnabler[];
  49. IMPORT int pccardEnablerNumEnt;
  50. /* globals */
  51. SEMAPHORE cisMuteSem;
  52. /* locals */
  53. LOCAL u_char powerMantissa [] = {10, 12, 13, 15, 20, 25, 30, 35,
  54.  40, 45, 50, 55, 60, 70, 80, 90};
  55. LOCAL u_char powerExponent [] = {0, 0, 0, 0, 0, 1, 10, 100};
  56. /* forward declarations */
  57. LOCAL STATUS cisTupleGet (int sock);
  58. LOCAL STATUS cisConfigGet (int sock);
  59. LOCAL STATUS cisResourceGet (int sock);
  60. /*******************************************************************************
  61. *
  62. * cisGet - get information from a PC card's CIS
  63. *
  64. * This routine gets information from a PC card's CIS, configures the PC card,
  65. * and allocates resources for the PC card.
  66. *
  67. * RETURNS: OK, or ERROR if it cannot get the CIS information,
  68. * configure the PC card, or allocate resources.
  69. */
  70. STATUS cisGet
  71.     (
  72.     int sock /* socket no. */
  73.     )
  74.     {
  75.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  76.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  77.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  78.     STATUS status = ERROR;
  79.     DL_NODE *pNode;
  80.     DL_NODE *pTemp;
  81.     semTake (&cisMuteSem, WAIT_FOREVER); /* mutual exclusion begin */
  82.     (void) (* pChip->cscOff) (sock, pChip->intLevel);
  83.     for (pNode = DLL_FIRST(&pCard->cisTupleList); pNode != NULL; pNode = pTemp)
  84. {
  85. pTemp = DLL_NEXT(pNode);
  86. free (pNode);
  87. }
  88.     for (pNode = DLL_FIRST(&pCard->cisConfigList); pNode != NULL; pNode = pTemp)
  89. {
  90. pTemp = DLL_NEXT(pNode);
  91. free (pNode);
  92. }
  93.     dllInit (&pCard->cisTupleList);
  94.     dllInit (&pCard->cisConfigList);
  95.     if ((cisTupleGet (sock) == OK) &&
  96. (cisConfigGet (sock) == OK) &&
  97.      (cisResourceGet (sock) == OK))
  98. status = OK;
  99.     (void) (* pChip->cscPoll) (sock);
  100.     (void) (* pChip->cscOn) (sock, pChip->intLevel);
  101.     semGive (&cisMuteSem); /* mutual exclusion end */
  102.     return (status);
  103.     }
  104. /*******************************************************************************
  105. *
  106. * cisTupleGet - get tuples from PC card and attach it to the link list
  107. *
  108. * This routine get tuples from PC card and attach it to the link list.
  109. *
  110. * RETURNS: OK, or ERROR if it couldn't set a value to the PCMCIA chip.
  111. */
  112. LOCAL STATUS cisTupleGet
  113.     (
  114.     int sock /* socket no. */
  115.     )
  116.     {
  117.     BOOL endList = FALSE;
  118.     BOOL noLink = FALSE;
  119.     u_long longlinkA = 0;
  120.     u_long longlinkC = 0;
  121.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  122.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  123.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  124.     int ix = 0;
  125.     PCMCIA_MEMWIN cisMemwin;
  126.     CIS_TUPLE_A *pTupleA;
  127.     CIS_TUPLE_C *pTupleC;
  128.     DL_NODE *pNode;
  129.     u_char *pChar;
  130.     u_char *pd;
  131.     u_char *ps;
  132.     int flag;
  133.     int tuples;
  134.     /* XXX
  135.      * Assumption
  136.      * 1. CIS tuple chain is in between start and stop in pcmciaMemwin[0].
  137.      * 2. Longlink from Common memory to Attribute memory doesn't occur
  138.      *
  139.      * Card reset/power signal sequence (See p.60 PCMCIA Developer's guide)
  140.      *                  ______________________________________________
  141.      *   Card detect  __|
  142.      *                   >50ms-
  143.      *                         _______________________________________
  144.      *   Vcc          _________|
  145.      *                          >300ms--------
  146.      *   Card signal                          ________________________
  147.      *       enabled  ________________________|
  148.      *                                        __________
  149.      *   Reset        ________________________|        |______________
  150.      *                                         >10ms---
  151.      *                                                  >20ms----
  152.      *   Card access                                             _____
  153.      *       allowed  ___________________________________________|
  154.      */
  155.     if (pChip->installed != TRUE)
  156. return (ERROR);
  157.     taskDelay (sysClkRateGet() >> 3); /* 7 * 16ms = 112ms */
  158.     if ((* pChip->reset)(sock) != OK)
  159. return (ERROR);
  160.     flag = PC_PWR_AUTO | PC_VCC_5V | PC_VPP_5V;
  161.     if ((* pChip->flagSet)(sock, flag) != OK)
  162. return (ERROR);
  163.     taskDelay (sysClkRateGet() >> 1); /* 30 * 16ms = 500ms */
  164.     flag = PC_PWR_AUTO | PC_VCC_5V | PC_VPP_5V | PC_RESET;
  165.     if ((* pChip->flagSet)(sock, flag) != OK)
  166. return (ERROR);
  167.     taskDelay (sysClkRateGet() >> 4); /* 3 * 16ms = 48ms */
  168.     flag = PC_PWR_AUTO | PC_VCC_5V | PC_VPP_5V;
  169.     if ((* pChip->flagSet)(sock, flag) != OK)
  170. return (ERROR);
  171.     taskDelay (sysClkRateGet() >> 2); /* 15 * 16ms = 240ms */
  172.     flag = PC_READY | PC_POWERON;
  173.     while ((((* pChip->status)(sock) & flag) != flag) && (ix++ < 8))
  174. taskDelay (sysClkRateGet() >> 2);
  175.     do  {
  176. /* map attribute memory */
  177. pChar = (u_char *)pcmciaMemwin[CIS_MEM_TUPLE].start +
  178.   pCtrl->memBase;
  179.         cisMemwin.window = PCMCIA_CIS_WINDOW;
  180.         cisMemwin.flags = MAP_ACTIVE | MAP_16BIT | MAP_ATTRIB;
  181.         cisMemwin.extraws = 2;
  182.         cisMemwin.start = pcmciaMemwin[CIS_MEM_TUPLE].start;
  183.         cisMemwin.stop = pcmciaMemwin[CIS_MEM_TUPLE].stop;
  184.         cisMemwin.cardstart = longlinkA;
  185. if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
  186.     return (ERROR);
  187. /* check the link target tuple if we had longlink tuple */
  188. if (longlinkA != 0)
  189.     {
  190.     longlinkA = 0;
  191.     pTupleA = (CIS_TUPLE_A *)pChar;
  192.     if (pTupleA->code == CISTPL_LINKTARGET)
  193. pChar += (pTupleA->link + 2) * 2;
  194.     else
  195. break;
  196.     }
  197. /* parse the tuple chain */
  198. endList = FALSE;
  199. for (tuples = 0; !endList; tuples++)
  200.     {
  201.     pTupleA = (CIS_TUPLE_A *)pChar;
  202.     switch (pTupleA->code)
  203. {
  204. case CISTPL_NULL:
  205.     pChar += 2;
  206.     break;
  207. case CISTPL_LONGLINK_A:
  208.     ps = pChar + 4;
  209.     pd = (u_char *)&longlinkA;
  210.     for (ix = 0; ix < 4; ix++)
  211. *pd++ = *ps++;
  212.     pChar += (pTupleA->link + 2) * 2;
  213.     break;
  214. case CISTPL_LONGLINK_C:
  215.     ps = pChar + 4;
  216.     pd = (u_char *)&longlinkC;
  217.     for (ix = 0; ix < 4; ix++)
  218. *pd++ = *ps++;
  219.     pChar += (pTupleA->link + 2) * 2;
  220.     break;
  221. case CISTPL_NO_LINK:
  222.     noLink = TRUE;
  223.     pChar += (pTupleA->link + 2) * 2;
  224.     break;
  225. case CISTPL_END:
  226.     if (tuples != 0)
  227.         endList = TRUE;
  228.     pChar += (pTupleA->link + 2) * 2;
  229.     break;
  230. case CISTPL_CHECKSUM:
  231.     /* XXX ignore now */
  232.     pChar += (pTupleA->link + 2) * 2;
  233.     break;
  234. default:
  235.     pNode = (DL_NODE *)malloc (pTupleA->link + 2 +
  236.        sizeof(DL_NODE));
  237.     pd = (u_char *)pNode + sizeof(DL_NODE);
  238.     ps = pChar;
  239.     for (ix = 0; ix < (pTupleA->link + 2); ix++)
  240. {
  241. *pd++ = *ps++;
  242. ps++;
  243. }
  244.     dllAdd (&pCard->cisTupleList, pNode);
  245.     pChar += (pTupleA->link + 2) * 2;
  246.     break;
  247. }
  248.     if ((pTupleA->link == 0xff) || (tuples >= CIS_MAX_TUPLES))
  249. endList = TRUE;
  250.     }
  251. } while (longlinkA != 0);
  252.     if (noLink)
  253. {
  254.         /* unmap memory window */
  255.         cisMemwin.window = 0;
  256.         cisMemwin.flags = 0;
  257.         cisMemwin.extraws = 0;
  258.         cisMemwin.start = 0;
  259.         cisMemwin.stop = 0;
  260.         cisMemwin.cardstart = 0;
  261.         if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
  262.             return (ERROR);
  263.         return (OK);
  264. }
  265.     do  {
  266. /* map common memory */
  267. pChar = (u_char *)pcmciaMemwin[CIS_MEM_TUPLE].start +
  268.   pCtrl->memBase;
  269.         cisMemwin.window = PCMCIA_CIS_WINDOW;
  270.         cisMemwin.flags = MAP_ACTIVE | MAP_16BIT;
  271.         cisMemwin.extraws = 2;
  272.         cisMemwin.start = pcmciaMemwin[CIS_MEM_TUPLE].start;
  273.         cisMemwin.stop = pcmciaMemwin[CIS_MEM_TUPLE].stop;
  274.         cisMemwin.cardstart = longlinkC;
  275. if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
  276.     return (ERROR);
  277. /* check the link target tuple */
  278. pTupleC = (CIS_TUPLE_C *)pChar;
  279. if (pTupleC->code == CISTPL_LINKTARGET)
  280.     pChar += pTupleC->link + 2;
  281. else
  282.     break;
  283. /* parse the tuple chain */
  284. endList = FALSE;
  285. for (tuples = 0; !endList; tuples++)
  286.     {
  287.     pTupleC = (CIS_TUPLE_C *)pChar;
  288.     switch (pTupleC->code)
  289. {
  290. case CISTPL_NULL:
  291.     pChar++;
  292.     break;
  293. case CISTPL_LONGLINK_A:
  294.     ps = pChar + 2;
  295.     pd = (u_char *)&longlinkA;
  296.     for (ix = 0; ix < 4; ix++)
  297. *pd++ = *ps++;
  298.     
  299.     pChar += pTupleC->link + 2;
  300.     break;
  301. case CISTPL_LONGLINK_C:
  302.     ps = pChar + 2;
  303.     pd = (u_char *)&longlinkC;
  304.     for (ix = 0; ix < 4; ix++)
  305. *pd++ = *ps++;
  306.     
  307.     pChar += pTupleC->link + 2;
  308.     break;
  309. case CISTPL_NO_LINK:
  310.     noLink = TRUE;
  311.     pChar += pTupleC->link + 2;
  312.     break;
  313. case CISTPL_END:
  314.     if (tuples != 0)
  315.         endList = TRUE;
  316.     pChar += pTupleC->link + 2;
  317.     break;
  318. case CISTPL_CHECKSUM:
  319.     /* XXX ignore now */
  320.     pChar += pTupleC->link + 2;
  321.     break;
  322. default:
  323.     pNode = (DL_NODE *)malloc (pTupleC->link + 2 + 
  324.        sizeof(DL_NODE));
  325.     pd = (u_char *)pNode + sizeof(DL_NODE);
  326.     ps = pChar;
  327.     for (ix = 0; ix < (pTupleC->link + 2); ix++)
  328. *pd++ = *ps++;
  329.     dllAdd (&pCard->cisTupleList, pNode);
  330.     pChar += pTupleC->link + 2;
  331.     break;
  332. }
  333.     if ((pTupleC->link == 0xff) || (tuples >= CIS_MAX_TUPLES))
  334. endList = TRUE;
  335.     }
  336. } while (longlinkC != 0);
  337.     /* unmap memory window */
  338.     cisMemwin.window = 0;
  339.     cisMemwin.flags = 0;
  340.     cisMemwin.extraws = 0;
  341.     cisMemwin.start = 0;
  342.     cisMemwin.stop = 0;
  343.     cisMemwin.cardstart = 0;
  344.     if ((* pChip->memwinSet)(sock, &cisMemwin) != OK)
  345.         return (ERROR);
  346.     return (OK);
  347.     }
  348. /*******************************************************************************
  349. *
  350. * cisConfigGet - get configuration information from the CIS tuple link list
  351. *
  352. * Get configuration information from the CIS tuple link list.
  353. *
  354. * RETURNS: OK (always).
  355. */
  356. LOCAL STATUS cisConfigGet
  357.     (
  358.     int sock /* socket no. */
  359.     )
  360.     {
  361.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  362.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  363.     CIS_CONFIG *pDefault = 0;
  364.     CIS_CONFIG *pConfig;
  365.     DL_NODE *pNode;
  366.     CIS_TUPLE *pTuple;
  367.     CIS_BYTE4 base;
  368.     CIS_BYTE4 mask;
  369.     CIS_BYTE4 addr;
  370.     CIS_BYTE4 length;
  371.     CIS_BYTE4 cAddr;
  372.     CIS_BYTE4 hAddr;
  373.     int lengthSize;
  374.     int addrSize;
  375.     int maskSize;
  376.     int windows;
  377.     int ix;
  378.     u_char *pChar;
  379.     u_char *pEnd;
  380.     u_char *pv;
  381.     u_char featureSelection;
  382.     u_char parameterSelection;
  383.     u_char hostaddr;
  384.     u_char waitScale;
  385.     u_char busyScale;
  386.     u_char reservedScale;
  387.     for (pNode = DLL_FIRST (&pCard->cisTupleList);
  388.  pNode != NULL;
  389.  pNode = DLL_NEXT(pNode))
  390. {
  391. pTuple = (CIS_TUPLE *)((char *)pNode + sizeof (DL_NODE));
  392. pChar = (u_char *)pTuple + sizeof (CIS_TUPLE);
  393. pEnd = pChar + pTuple->link;
  394. switch (pTuple->code)
  395.     {
  396.     case CISTPL_CONFIG:
  397. pCard->regBase = 0;
  398. pCard->regMask = 0;
  399. addrSize = (*pChar & 0x03) + 1;
  400. maskSize = ((*pChar & 0x3c) >> 2) + 1;
  401. pChar += 2;
  402. if (pChar > pEnd)
  403.     break;
  404. base.l = 0;
  405. for (ix = 0; ix < addrSize; ix++)
  406.     base.c[ix] = *pChar++;
  407. mask.l = 0;
  408. for (ix = 0; ix < maskSize; ix++)
  409.     mask.c[ix] = *pChar++;
  410. pCard->regBase = base.l;
  411. pCard->regMask = mask.l;
  412. break;
  413.     
  414.     case CISTPL_CFTABLE_ENTRY:
  415. pConfig = (CIS_CONFIG *)calloc(1, sizeof(CIS_CONFIG));
  416. if (*pChar & 0x40)
  417.     pDefault = pConfig;
  418. else if (pDefault != 0)
  419.     {
  420.     bcopy ((char *)pDefault, (char *)pConfig, 
  421.    sizeof(CIS_CONFIG));
  422.     dllInit ((DL_LIST *)&pConfig->node);
  423.     }
  424. dllAdd (&pCard->cisConfigList, &pConfig->node);
  425. pConfig->index = *pChar & 0x3f;
  426. if (*pChar++ & 0x80)
  427.     pConfig->interfaceType = *pChar++ & 0x0f;
  428. featureSelection = *pChar++;
  429. if (featureSelection & 0x03) /* power description */
  430.     {
  431.     for (ix=1; ix <= (featureSelection & 0x03); ix++)
  432. {
  433. if (ix == 1)
  434.     pv = &pConfig->vcc[0];
  435. else if (ix == 2)
  436.     pv = &pConfig->vpp1[0];
  437. else
  438.     pv = &pConfig->vpp2[0];
  439. parameterSelection = *pChar++;
  440. if (parameterSelection & 0x01)
  441.     {
  442.     *pv++ = powerMantissa[(*pChar & 0x78) >> 3] *
  443.     powerExponent[(*pChar & 0x07)];
  444.     while (*pChar++ & 0x80)
  445. ;
  446.     }
  447. if (parameterSelection & 0x02)
  448.     {
  449.     *pv++ = powerMantissa[(*pChar & 0x78) >> 3] *
  450.     powerExponent[(*pChar & 0x07)];
  451.     while (*pChar++ & 0x80)
  452. ;
  453.     }
  454. if (parameterSelection & 0x04)
  455.     {
  456.     *pv++ = powerMantissa[(*pChar & 0x78) >> 3] *
  457.     powerExponent[(*pChar & 0x07)];
  458.     while (*pChar++ & 0x80)
  459. ;
  460.     }
  461. if (parameterSelection & 0x08)
  462.     {
  463.     while (*pChar++ & 0x80)
  464. ;
  465.     }
  466. if (parameterSelection & 0x10)
  467.     {
  468.     while (*pChar++ & 0x80)
  469. ;
  470.     }
  471. if (parameterSelection & 0x20)
  472.     {
  473.     while (*pChar++ & 0x80)
  474. ;
  475.     }
  476. if (parameterSelection & 0x40)
  477.     {
  478.     while (*pChar++ & 0x80)
  479. ;
  480.     }
  481. }
  482.     }
  483. if (featureSelection & 0x04) /* timing description */
  484.     {
  485.     waitScale   = *pChar & 0x03;
  486.     busyScale   = (*pChar & 0x1c) >> 2;
  487.     reservedScale = (*pChar & 0xe0) >> 5;
  488.     pChar++;
  489.     if (waitScale != 0x03)
  490. while (*pChar++ & 0x80)
  491.     ;
  492.     if (busyScale != 0x03)
  493. while (*pChar++ & 0x80)
  494.     ;
  495.     if (reservedScale != 0x03)
  496. while (*pChar++ & 0x80)
  497.     ;
  498.     }
  499. if (featureSelection & 0x08) /* IO description */
  500.     {
  501.     pConfig->ioAddrlines = *pChar & 0x1f;
  502.     pConfig->ioBuswidth  = (*pChar & 0x60) >> 5;
  503.     pConfig->ioRanges  = 0;
  504.     if (*pChar++ & 0x80)
  505. {
  506. pConfig->ioRanges = (*pChar & 0x07) + 1;
  507. addrSize   = (*pChar & 0x30) >> 4;
  508. lengthSize = (*pChar & 0xc0) >> 6;
  509. pChar++;
  510. for (ix = 0; ix < pConfig->ioRanges; ix++)
  511.     {
  512.     addr.l = 0;
  513.     if (addrSize == 1)
  514. addr.c[0] = *pChar++;
  515.     else if (addrSize == 2)
  516. {
  517. addr.c[0] = *pChar++;
  518. addr.c[1] = *pChar++;
  519. }
  520.     else if (addrSize == 3)
  521. {
  522. addr.c[0] = *pChar++;
  523. addr.c[1] = *pChar++;
  524. addr.c[2] = *pChar++;
  525. addr.c[3] = *pChar++;
  526. }
  527.     length.l = 0;
  528.     if (lengthSize == 1)
  529. length.c[0] = *pChar++;
  530.     else if (lengthSize == 2)
  531. {
  532. length.c[0] = *pChar++;
  533. length.c[1] = *pChar++;
  534. }
  535.     else if (lengthSize == 3)
  536. {
  537. length.c[0] = *pChar++;
  538. length.c[1] = *pChar++;
  539. length.c[2] = *pChar++;
  540. length.c[3] = *pChar++;
  541. }
  542.     pConfig->io[ix].start = addr.l;
  543.     pConfig->io[ix].stop  = addr.l + length.l;
  544.     }
  545. }
  546.     }
  547. if (featureSelection & 0x10) /* IRQ description */
  548.     {
  549.     pConfig->irqMode = (*pChar & 0xe0) >> 5;
  550.     pConfig->irqMask = (*pChar & 0x10) >> 4;
  551.     if (pConfig->irqMask == 1)
  552. {
  553. pConfig->irqSpecial  = *pChar++ & 0x0f;
  554. pConfig->irqBit.c[0] = *pChar++;
  555. pConfig->irqBit.c[1] = *pChar++;
  556. }
  557.     else
  558. {
  559. pConfig->irqSpecial  = 0;
  560. pConfig->irqBit.c[0] = 0;
  561. pConfig->irqBit.c[1] = 0;
  562. pConfig->irqLevel    = *pChar++ & 0x0f;
  563. }
  564.     }
  565. if (featureSelection & 0x60) /* memory description */
  566.     {
  567.     if ((featureSelection & 0x60) == 0x20)
  568. {
  569. length.l = 0;
  570. length.c[0] = *pChar++;
  571. length.c[1] = *pChar++;
  572. pConfig->mem[0].length = length.l;
  573. pConfig->mem[0].cAddr  = 0;
  574. pConfig->mem[0].hAddr  = 0;
  575. }
  576.     else if ((featureSelection & 0x60) == 0x40)
  577. {
  578. length.l    = 0;
  579. cAddr.l     = 0;
  580. length.c[0] = *pChar++;
  581. length.c[1] = *pChar++;
  582. cAddr.c[0]  = *pChar++;
  583. cAddr.c[1]  = *pChar++;
  584. pConfig->mem[0].length = length.l;
  585. pConfig->mem[0].cAddr  = cAddr.l;
  586. pConfig->mem[0].hAddr  = 0;
  587. }
  588.     else if ((featureSelection & 0x60) == 0x60)
  589. {
  590. windows    = (*pChar & 0x07) + 1;
  591. lengthSize = (*pChar & 0x18) >> 3;
  592. addrSize   = (*pChar & 0x60) >> 5;
  593. hostaddr   = *pChar & 0x80;
  594. for (ix = 0; ix < windows; ix++)
  595.     {
  596.     length.l = 0;
  597.     cAddr.l  = 0;
  598.     hAddr.l  = 0;
  599.     if (lengthSize == 1)
  600. length.c[0] = *pChar++;
  601.     else if (lengthSize == 2)
  602. {
  603. length.c[0] = *pChar++;
  604. length.c[1] = *pChar++;
  605. }
  606.     else if (lengthSize == 3)
  607. {
  608. length.c[0] = *pChar++;
  609. length.c[1] = *pChar++;
  610. length.c[2] = *pChar++;
  611. length.c[3] = *pChar++;
  612. }
  613.     if (addrSize == 1)
  614. cAddr.c[0] = *pChar++;
  615.     else if (addrSize == 2)
  616. {
  617. cAddr.c[0] = *pChar++;
  618. cAddr.c[1] = *pChar++;
  619. }
  620.     else if (addrSize == 3)
  621. {
  622. cAddr.c[0] = *pChar++;
  623. cAddr.c[1] = *pChar++;
  624. cAddr.c[2] = *pChar++;
  625. cAddr.c[3] = *pChar++;
  626. }
  627.     
  628.     if (hostaddr == 0x80)
  629. {
  630.         if (addrSize == 1)
  631.     cAddr.c[0] = *pChar++;
  632.         else if (addrSize == 2)
  633.     {
  634.     cAddr.c[0] = *pChar++;
  635.     cAddr.c[1] = *pChar++;
  636.     }
  637.         else if (addrSize == 3)
  638.     {
  639.     cAddr.c[0] = *pChar++;
  640.     cAddr.c[1] = *pChar++;
  641.     cAddr.c[2] = *pChar++;
  642.     cAddr.c[3] = *pChar++;
  643.     }
  644. }
  645.     pConfig->mem[ix].length = length.l;
  646.     pConfig->mem[ix].cAddr  = cAddr.l;
  647.     pConfig->mem[ix].hAddr  = hAddr.l;
  648.     }
  649. }
  650.     }
  651. if (featureSelection & 0x80) /* misc info. description */
  652.     {
  653.     pConfig->twins    = *pChar & 0x07;
  654.     pConfig->audio    = (*pChar & 0x08) >> 3;
  655.     pConfig->readonly = (*pChar & 0x10) >> 4;
  656.     pConfig->pwrdown  = (*pChar & 0x20) >> 5;
  657.     }
  658. break;
  659.     }
  660. }
  661.     return (OK);
  662.     }
  663. /*******************************************************************************
  664. *
  665. * cisResourceGet - config the PC card from the configuration table link list
  666. *
  667. * Config the PC card from the configuration table link list.
  668. *
  669. * RETURNS: OK, or ERROR if the enabler couldn't initialize the PC card.
  670. */
  671. LOCAL STATUS cisResourceGet
  672.     (
  673.     int sock /* socket no. */
  674.     )
  675.     {
  676.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  677.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  678.     STATUS status = ERROR;
  679.     PCCARD_ENABLER *pEnabler;
  680.     int ix;
  681.     for (ix = 0; ix < pccardEnablerNumEnt; ix++)
  682. {
  683. pEnabler = &pccardEnabler[ix];
  684. if (pEnabler->enableRtn != NULL)
  685.     {
  686.     if ((pCard->initStatus = (* pEnabler->enableRtn) (
  687. sock, 
  688. pEnabler->pResource,
  689. pEnabler->resourceNumEnt,
  690. pEnabler->showRtn)) == ERROR_FIND)
  691. {
  692. continue;
  693. }
  694.     else
  695. {
  696. break;
  697. }
  698.     }
  699. }
  700.     if (pCard->initStatus == OK)
  701. status = OK;
  702.     return (status);
  703.     }
  704. /*******************************************************************************
  705. *
  706. * cisFree - free tuples from the linked list
  707. *
  708. * This routine free tuples from the linked list.
  709. *
  710. * RETURNS: N/A
  711. *
  712. * INTERNAL
  713. * This funcion should not do it by itself, it should called an enabler
  714. * supplied destroy function to delete the device (if possible) in device
  715. * dependent manner.
  716. */
  717. void cisFree
  718.     (
  719.     int sock /* socket no. */
  720.     )
  721.     {
  722.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  723.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  724.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  725.     PCMCIA_IOWIN iowin;
  726.     PCMCIA_MEMWIN memwin;
  727.     DL_NODE *pNode;
  728.     DL_NODE *pTemp;
  729.     int ix;
  730.     semTake (&cisMuteSem, WAIT_FOREVER); /* mutual exclusion begin */
  731.     (void) (* pChip->cscOff) (sock, pChip->intLevel);
  732.     pCard->type = 0;
  733.     pCard->sock = 0;
  734.     pCard->ctrl = 0;
  735.     pCard->detected = FALSE;
  736.     pCard->installed = FALSE;
  737.     pCard->changed = TRUE;
  738.     pCard->regBase = 0;
  739.     pCard->regMask = 0;
  740.     pCard->initStatus = 0;
  741.     pCard->cscIntr = NULL;
  742.     pCard->showRtn = NULL;
  743.     pCard->pResource = NULL;
  744.     if (pCard->pBlkDev != NULL)
  745.         pCard->pBlkDev->bd_readyChanged = TRUE ;
  746.     if (pCard->pNetIf != NULL)
  747.         free ((char *)pCard->pNetIf);  /* XXX - lrn */
  748.     pCard->pNetIf = NULL;
  749.     if (pCard->pDos != NULL)
  750. {
  751. #if FALSE /* DosFs 2.0 - can not remove dos device */
  752. iosDevDelete (&pCard->pDos->dosvd_devHdr);
  753. free ((char *)pCard->pDos);
  754. #endif /*FALSE*/
  755. }
  756.     pCard->pDos = NULL;
  757.     for (pNode = DLL_FIRST(&pCard->cisTupleList); pNode != NULL; pNode = pTemp)
  758. {
  759. pTemp = DLL_NEXT(pNode);
  760. free (pNode);
  761. }
  762.     dllInit (&pCard->cisTupleList);
  763.     for (pNode = DLL_FIRST(&pCard->cisConfigList); pNode != NULL; pNode = pTemp)
  764. {
  765. pTemp = DLL_NEXT(pNode);
  766. free (pNode);
  767. }
  768.     dllInit (&pCard->cisConfigList);
  769.     (void) (* pChip->irqSet) (sock, 0);
  770.     (void) (* pChip->flagSet) (sock, PC_PWR_AUTO);
  771.     memwin.window = 0;
  772.     memwin.flags = 0;
  773.     memwin.extraws = 0;
  774.     memwin.start = 0;
  775.     memwin.stop = 0;
  776.     memwin.cardstart = 0;
  777.     for (ix = 0; ix < pChip->memWindows; ix++)
  778. {
  779.         memwin.window = ix;
  780.         (void) (* pChip->memwinSet) (sock, &memwin);
  781. }
  782.     iowin.window = 0;
  783.     iowin.flags = 0;
  784.     iowin.extraws = 0;
  785.     iowin.start = 0;
  786.     iowin.stop = 0;
  787.     for (ix = 0; ix < pChip->ioWindows; ix++)
  788. {
  789.         iowin.window = ix;
  790.         (void) (* pChip->iowinSet) (sock, &iowin);
  791. }
  792.     (void) (* pChip->cscPoll) (sock);
  793.     (void) (* pChip->cscOn) (sock, pChip->intLevel);
  794.     semGive (&cisMuteSem); /* mutual exclusion end */
  795.     }
  796. /*******************************************************************************
  797. *
  798. * cisConfigregGet - get the PCMCIA configuration register
  799. *
  800. * This routine gets that PCMCIA configuration register.
  801. *
  802. * RETURNS: OK, or ERROR if it cannot set a value on the PCMCIA chip.
  803. */
  804. STATUS cisConfigregGet
  805.     (
  806.     int sock, /* socket no. */
  807.     int reg, /* configuration register no. */
  808.     int *pValue /* content of the register */
  809.     )
  810.     {
  811.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  812.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  813.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  814.     PCMCIA_MEMWIN memWin;
  815.     char *pReg;
  816.     if ((pCard->regBase == 0) || ((pCard->regMask & (1 << reg)) == 0) ||
  817.         (pChip->installed != TRUE))
  818. return (ERROR);
  819.     
  820.     memWin.window = PCMCIA_CIS_WINDOW;
  821.     memWin.flags = MAP_ACTIVE | MAP_16BIT | MAP_ATTRIB;
  822.     memWin.extraws = 2;
  823.     memWin.start = pcmciaMemwin[CIS_MEM_CONFIG].start;
  824.     memWin.stop = pcmciaMemwin[CIS_MEM_CONFIG].stop;
  825.     memWin.cardstart = pCard->regBase;
  826.     if ((* pChip->memwinSet)(sock, &memWin) != OK)
  827. return (ERROR);
  828.     pReg = (char *)memWin.start + (pCard->regBase & 0xfff) + (reg * 2) +
  829.    pCtrl->memBase;
  830.     *pValue = *pReg;
  831.     memWin.window = 0;
  832.     memWin.flags = 0;
  833.     memWin.extraws = 0;
  834.     memWin.start = 0;
  835.     memWin.stop = 0;
  836.     memWin.cardstart = 0;
  837.     if ((* pChip->memwinSet)(sock, &memWin) != OK)
  838. return (ERROR);
  839.     
  840.     return (OK);
  841.     }
  842. /*******************************************************************************
  843. *
  844. * cisConfigregSet - set the PCMCIA configuration register
  845. *
  846. * This routine sets the PCMCIA configuration register.
  847. *
  848. * RETURNS: OK, or ERROR if it cannot set a value on the PCMCIA chip.
  849. */
  850. STATUS cisConfigregSet
  851.     (
  852.     int sock, /* socket no. */
  853.     int reg, /* register no. */
  854.     int value /* content of the register */
  855.     )
  856.     {
  857.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  858.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  859.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  860.     PCMCIA_MEMWIN memWin;
  861.     char *pReg;
  862.     if ((pCard->regBase == 0) || ((pCard->regMask & (1 << reg)) == 0) ||
  863.         (pChip->installed != TRUE))
  864. return (ERROR);
  865.     
  866.     memWin.window = PCMCIA_CIS_WINDOW;
  867.     memWin.flags = MAP_ACTIVE | MAP_16BIT | MAP_ATTRIB;
  868.     memWin.extraws = 2;
  869.     memWin.start = pcmciaMemwin[CIS_MEM_CONFIG].start;
  870.     memWin.stop = pcmciaMemwin[CIS_MEM_CONFIG].stop;
  871.     memWin.cardstart = pCard->regBase;
  872.     if ((* pChip->memwinSet)(sock, &memWin) != OK)
  873. return (ERROR);
  874.     pReg = (char *)memWin.start + (pCard->regBase & 0xfff) + (reg * 2) +
  875.    pCtrl->memBase;
  876.     *pReg = value;
  877.     memWin.window = 0;
  878.     memWin.flags = 0;
  879.     memWin.extraws = 0;
  880.     memWin.start = 0;
  881.     memWin.stop = 0;
  882.     memWin.cardstart = 0;
  883.     if ((* pChip->memwinSet)(sock, &memWin) != OK)
  884. return (ERROR);
  885.     
  886.     return (OK);
  887.     }