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

VxWorks

开发平台:

C/C++

  1. /* pcic.c - Intel 82365SL PCMCIA host bus adaptor chip library */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. /* Copyright (c) 1994 David A. Hinds -- All Rights Reserved */
  4. #include "copyright_wrs.h"
  5. /*
  6. modification history
  7. --------------------
  8. 01h,01apr98,hdn  set PCIC_ENA_MEMCS16 if MAP_16BIT is specified.
  9. 01g,19jan98,hdn  removed taskDelay().
  10. 01f,01nov96,hdn  fixed PCIC_PORT().
  11. 01e,29mar96,jdi  doc: fixed error.
  12. 01d,28mar96,jdi  doc: cleaned up language and format.
  13. 01c,08mar96,hdn  added more descriptions.
  14. 01b,22feb96,hdn  cleaned up
  15. 01a,19jan95,hdn  written based on David Hinds's version 2.2.3.
  16. */
  17. /*
  18. DESCRIPTION
  19. This library contains routines to manipulate the PCMCIA functions on the
  20. Intel 82365 series PCMCIA chip.
  21. The following compatible chips are also supported:
  22.     - Cirrus Logic PD6712/20/22
  23.     - Vadem VG468
  24.     - VLSI 82c146
  25.     - Ricoh RF5C series
  26. The initialization routine pcicInit() is the only global function and is
  27. included in the PCMCIA chip table `pcmciaAdapter'.  If pcicInit() finds
  28. the PCIC chip, it registers all function pointers of the PCMCIA_CHIP
  29. structure.
  30. */
  31. #include "vxWorks.h"
  32. #include "taskLib.h"
  33. #include "intLib.h"
  34. #include "sysLib.h"
  35. #include "drv/pcmcia/pcmciaLib.h"
  36. #include "drv/pcmcia/pcic.h"
  37. #include "drv/pcmcia/pd67.h"
  38. #include "drv/pcmcia/vg468.h"
  39. #include "drv/pcmcia/ricoh.h"
  40. /* defines */
  41. #define PCIC_PORT(slot) (pcicBase + (2*((slot) >> 2)))
  42. #define PCIC_REG(slot, reg) ((((slot) & 3) * 0x40) + reg)
  43. /* imports */
  44. IMPORT PCMCIA_CTRL pcmciaCtrl;
  45. /* globals */
  46. int pcicBase;
  47. /* locals */
  48. LOCAL SEMAPHORE pcicMuteSem;
  49. /* forward declarations */
  50. LOCAL STATUS pcicReset (int sock);
  51. LOCAL int pcicStatus (int sock);
  52. LOCAL int pcicFlagGet (int sock);
  53. LOCAL STATUS pcicFlagSet (int sock, int flag);
  54. LOCAL STATUS pcicCscOn (int sock, int irq);
  55. LOCAL STATUS pcicCscOff (int sock, int irq);
  56. LOCAL int pcicCscPoll (int sock);
  57. LOCAL int pcicIrqGet (int sock);
  58. LOCAL STATUS pcicIrqSet (int sock, int irq);
  59. LOCAL STATUS pcicIowinGet (int sock, PCMCIA_IOWIN *io);
  60. LOCAL STATUS pcicIowinSet (int sock, PCMCIA_IOWIN *io);
  61. LOCAL STATUS pcicMemwinGet (int sock, PCMCIA_MEMWIN *mem);
  62. LOCAL STATUS pcicMemwinSet (int sock, PCMCIA_MEMWIN *mem);
  63. LOCAL int pcicGet (int sock, int reg);
  64. LOCAL int pcicGet2 (int sock, int reg);
  65. LOCAL void pcicSet (int sock, int reg, char value);
  66. LOCAL void pcicSet2 (int sock, int reg, short value);
  67. LOCAL void pcicBset (int sock, int reg, char mask);
  68. LOCAL void pcicBclr (int sock, int reg, char mask);
  69. /*******************************************************************************
  70. *
  71. * pcicInit - initialize the PCIC chip
  72. *
  73. * This routine initializes the PCIC chip.
  74. *
  75. * RETURNS: OK, or ERROR if the PCIC chip cannot be found.
  76. */
  77. STATUS pcicInit
  78.     (
  79.     int     ioBase, /* IO base address */
  80.     int     intVec, /* interrupt vector */
  81.     int     intLevel, /* interrupt level */
  82.     FUNCPTR showRtn /* show routine */
  83.     )
  84.     {
  85.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  86.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  87.     BOOL done = FALSE;
  88.     int ix;
  89.     int value;
  90.     int sock;
  91.     
  92.     pcicBase = ioBase;
  93.     for (sock = 0; sock < PCIC_MAX_SOCKS; sock++)
  94. {
  95. value = pcicGet (sock, PCIC_IDENT);
  96. switch (value)
  97.     {
  98.     case 0x82:
  99.     case 0x83:
  100. pChip->name = "INTEL 82365SL";
  101. pChip->type = PCIC_I82365;
  102. /* check for Vadem VG-468 chip */
  103. sysOutByte (PCIC_PORT (sock), 0x0e);
  104. sysOutByte (PCIC_PORT (sock), 0x37);
  105. pcicBset (sock, VG468_MISC, VG468_MISC_VADEMREV);
  106. value = pcicGet (sock, PCIC_IDENT);
  107. if (value & PCIC_IDENT_VADEM)
  108.     {
  109.     pChip->name = "VADEM Clone";
  110.     pChip->type = PCIC_VG468;
  111.     pcicBclr (sock, VG468_MISC, VG468_MISC_VADEMREV);
  112.     }
  113. break;
  114.     case 0x84:
  115. pChip->name = "VLSI 82C146";
  116. pChip->type = PCIC_VLSI;
  117. break;
  118.     case 0x88:
  119.     case 0x89:
  120. pChip->name = "IBM Clone";
  121. pChip->type = PCIC_IBM;
  122. break;
  123.     case 0x8b:
  124. pChip->name = "VADEM Clone";
  125. pChip->type = PCIC_VG468;
  126. pcicBclr (sock, VG468_MISC, VG468_MISC_VADEMREV);
  127. break;
  128.     default:
  129. done = 1;
  130.     }
  131. if (done)
  132.     break;
  133. pcicSet (sock, PCIC_CSCINT, sock);
  134. }
  135.     if (sock == 0)
  136. return (ERROR);
  137.     semMInit (&pcicMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE | 
  138.       SEM_INVERSION_SAFE);
  139.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  140.     /* Check for bogus clones that ignore top bit of index register */
  141.     if ((sock == 4) && (pcicGet (0, PCIC_CSCINT) == 2))
  142. sock = 2;
  143.     
  144.     /* Check for Ricoh chips */
  145.     value = pcicGet (0, RF5C_CHIP_ID);
  146.     if ((value == RF5C_CHIP_RF5C296) || (value == RF5C_CHIP_RF5C396))
  147. {
  148. pChip->name = "RICOH Clone";
  149. pChip->type = PCIC_RICOH;
  150. }
  151.     /* Check for Cirrus CL-PD67xx chips */
  152.     pcicSet (0, PD67_CHIP_INFO, 0);
  153.     value = pcicGet (0, PD67_CHIP_INFO);
  154.     if ((value & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID)
  155. {
  156. value = pcicGet (0, PD67_CHIP_INFO);
  157. if ((value & PD67_INFO_CHIP_ID) == 0)
  158.     {
  159.     if (value & PD67_INFO_SLOTS)
  160. {
  161. pChip->name = "Cirrus CL-PD672x";
  162. pChip->type = PCIC_PD672X;
  163. }
  164.     else
  165. {
  166. pChip->name = "Cirrus CL-PD6710";
  167. pChip->type = PCIC_PD6710;
  168. sock = 1;
  169.         }
  170.     }
  171.         }
  172.     for (ix = 0; ix < sock; ix++)
  173. {
  174.         pcicSet (sock, PCIC_CSCINT, 0);
  175.         pcicSet (sock, PCIC_GENCTL, 0);
  176.         pcicSet (sock, PCIC_GBLCTL, 0);
  177. }
  178.     
  179.     pChip->reset = (FUNCPTR) pcicReset;
  180.     pChip->status = (FUNCPTR) pcicStatus;
  181.     pChip->flagGet = (FUNCPTR) pcicFlagGet;
  182.     pChip->flagSet = (FUNCPTR) pcicFlagSet;
  183.     pChip->cscOn = (FUNCPTR) pcicCscOn;
  184.     pChip->cscOff = (FUNCPTR) pcicCscOff;
  185.     pChip->cscPoll = (FUNCPTR) pcicCscPoll;
  186.     pChip->irqGet = (FUNCPTR) pcicIrqGet;
  187.     pChip->irqSet = (FUNCPTR) pcicIrqSet;
  188.     pChip->iowinGet = (FUNCPTR) pcicIowinGet;
  189.     pChip->iowinSet = (FUNCPTR) pcicIowinSet;
  190.     pChip->memwinGet = (FUNCPTR) pcicMemwinGet;
  191.     pChip->memwinSet = (FUNCPTR) pcicMemwinSet;
  192.     pChip->type = PCMCIA_PCIC;
  193.     pChip->socks = sock;
  194.     pChip->installed = TRUE;
  195.     pChip->intLevel = intLevel;
  196.     pChip->memWindows = PCIC_MEM_WINDOWS;
  197.     pChip->ioWindows = PCIC_IO_WINDOWS;
  198.     pChip->showRtn = showRtn;
  199.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  200.     return (OK);
  201.     }
  202.   
  203. /*******************************************************************************
  204. *
  205. * pcicStatus - Get status of the socket.
  206. *
  207. * This routine gets status of the socket.
  208. * This routine can be called in interrupt level.
  209. *
  210. * RETURNS: The status of the socket.
  211. */
  212. LOCAL int pcicStatus
  213.     (
  214.     int sock /* socket no. */
  215.     )
  216.     {
  217.     BOOL intMode = intContext ();
  218.     int status = 0;
  219.     char value;
  220.     if (!intMode)
  221.         semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  222.     value  = pcicGet (sock, PCIC_STATUS);
  223.     if ((value & PCIC_CS_DETECT) == PCIC_CS_DETECT) /* CD1=1 and CD2=1 */
  224.         status = PC_IS_CARD;
  225.     if ((value & PCIC_CS_DETECT) != PCIC_CS_DETECT) /* CD1=0 or CD2=0 */
  226.         status = PC_NO_CARD;
  227.     if (pcicGet (sock, PCIC_INTCTL) & PCIC_PC_IOCARD)
  228. status |= (value & PCIC_CS_STSCHG) ? 0 : PC_STSCHG;
  229.     else
  230. {
  231. status |= (value & PCIC_CS_BVD1) ? 0 : PC_BATDEAD;
  232. status |= (value & PCIC_CS_BVD2) ? 0 : PC_BATWARN;
  233.         }
  234.     status |= (value & PCIC_CS_WRPROT) ? PC_WRPROT : 0;
  235.     status |= (value & PCIC_CS_READY) ? PC_READY : 0;
  236.     status |= (value & PCIC_CS_POWERON) ? PC_POWERON : 0;
  237.     if (!intMode)
  238.         semGive (&pcicMuteSem);   /* mutual execlusion stop */
  239.     return (status);
  240.     }
  241. /*******************************************************************************
  242. *
  243. * pcicFlagGet - Get configuration flag from the socket.
  244. *
  245. * This routine gets configuration flag from the socket.
  246. *
  247. * RETURNS: The configuration flag of the socket.
  248. */
  249. LOCAL int pcicFlagGet
  250.     (
  251.     int sock /* socket no. */
  252.     )
  253.     {
  254.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  255.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  256.     char value;
  257.     char vcc;
  258.     char vpp;
  259.     int flag;
  260.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  261.     value = pcicGet (sock, PCIC_POWER);
  262.     vcc   = value & PCIC_VCC_MASK;
  263.     vpp   = value & PCIC_VPP_MASK;
  264.     flag  = (value & PCIC_PWR_AUTO) ? PC_PWR_AUTO : 0;
  265.     switch (pChip->type)
  266. {
  267. case PCIC_PD672X:
  268. case PCIC_PD6710:
  269.     if (pcicGet (sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V)
  270. {
  271. flag |= (value & PCIC_VCC_5V) ? PC_VCC_3V : 0;
  272. flag |= (vpp & PCIC_VPP_5V) ? PC_VPP_5V : 0;
  273. flag |= (vpp & PCIC_VPP_12V) ? PC_VPP_12V : 0;
  274. }
  275.     else
  276. {
  277. flag |= (value & PCIC_VCC_5V) ? PC_VCC_5V : 0;
  278. flag |= (vpp & PCIC_VPP_5V) ? PC_VPP_5V : 0;
  279. flag |= (vpp & PCIC_VPP_12V) ? PC_VPP_12V : 0;
  280. }
  281.     break;
  282. case PCIC_VG468:
  283.     if (value & PCIC_VCC_5V)
  284. {
  285. flag = PC_VCC_5V;
  286. flag |= (vpp & PCIC_VPP_5V) ? PC_VPP_5V : 0;
  287. flag |= (vpp & PCIC_VPP_12V) ? PC_VPP_12V : 0;
  288. }
  289.     break;
  290. default:
  291.             flag |= (vcc & PCIC_VCC_3V) ? PC_VCC_3V : 0;
  292.             flag |= (vcc & PCIC_VCC_5V) ? PC_VCC_5V : 0;
  293.             flag |= (vpp & PCIC_VPP_5V) ? PC_VPP_5V : 0;
  294.             flag |= (vpp & PCIC_VPP_12V) ? PC_VPP_12V : 0;
  295.             break;
  296. }
  297.     value = pcicGet (sock, PCIC_INTCTL);
  298.     flag |= (value & PCIC_PC_IOCARD) ? PC_IOCARD : 0;
  299.     flag |= (value & PCIC_PC_RESET) ? 0 : PC_RESET;
  300.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  301.     return (flag);
  302.     }
  303. /*******************************************************************************
  304. *
  305. * pcicFlagSet - Set configuration flag into the socket.
  306. *
  307. * This routine sets configuration flag into the socket.
  308. *
  309. * RETURNS: OK (always).
  310. */
  311. LOCAL STATUS pcicFlagSet
  312.     (
  313.     int sock, /* socket no. */
  314.     int flag /* configuration flag */
  315.     )
  316.     {
  317.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  318.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  319.     char value;
  320.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  321.     value  = pcicGet (sock, PCIC_POWER);
  322.     value &= ~(PCIC_PWR_AUTO | PCIC_VCC_MASK | PCIC_VPP_MASK);
  323.     value |= (flag & PC_PWR_AUTO) ? PCIC_PWR_AUTO : 0;
  324.     switch (pChip->type)
  325. {
  326. case PCIC_PD672X:
  327. case PCIC_PD6710:
  328.     if (flag & PC_VPP_MASK)
  329. {
  330. if (flag & PC_VPP_12V)
  331.     value |= PCIC_VPP_12V;
  332. else if ((flag & PC_VPP_5V) && (flag & PC_VCC_5V))
  333.     value |= PCIC_VPP_5V;
  334. }
  335.     if (flag & PC_VCC_MASK)
  336. {
  337. if (flag & PC_VCC_3V)
  338.     {
  339.     value |= PCIC_VCC_5V | PCIC_PWR_OUT;
  340.     pcicBset (sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
  341.     }
  342. else if (flag & PC_VCC_5V)
  343.     {
  344.     value |= PCIC_VCC_5V | PCIC_PWR_OUT;
  345.     pcicBclr (sock, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
  346.     }
  347. }
  348.     break;
  349. case PCIC_VG468:
  350.             value |= (flag & PC_VCC_5V) ? PCIC_VCC_5V | PCIC_PWR_OUT : 0;
  351.             value |= (flag & PC_VPP_5V) ? PCIC_VPP_5V : 0;
  352.             value |= (flag & PC_VPP_12V) ? PCIC_VPP_12V : 0;
  353.     break;
  354. default:
  355.             value |= (flag & PC_VCC_3V) ? PCIC_VCC_3V | PCIC_PWR_OUT : 0;
  356.             value |= (flag & PC_VCC_5V) ? PCIC_VCC_5V | PCIC_PWR_OUT : 0;
  357.             value |= (flag & PC_VPP_5V) ? PCIC_VPP_5V : 0;
  358.             value |= (flag & PC_VPP_12V) ? PCIC_VPP_12V : 0;
  359.     break;
  360. }
  361.     pcicSet (sock, PCIC_POWER, value);
  362.     value = pcicGet (sock, PCIC_INTCTL);
  363.     value &= ~(PCIC_PC_IOCARD | PCIC_PC_RESET);
  364.     /* Note that the reset signal is inverted */
  365.     value |= (flag & PC_RESET) ? 0 : PCIC_PC_RESET;
  366.     value |= (flag & PC_IOCARD) ? PCIC_PC_IOCARD : 0;
  367.     pcicSet (sock, PCIC_INTCTL, value);
  368.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  369.     return (OK);
  370.     }
  371. /*******************************************************************************
  372. *
  373. * pcicCscOn - Enables the card status change interrupt.
  374. *
  375. * This routine enables the card status change interrupt.
  376. *
  377. * RETURNS: OK (always).
  378. */
  379. LOCAL STATUS pcicCscOn
  380.     (
  381.     int sock, /* socket no. */
  382.     int irq /* IRQ level for CSC */
  383.     )
  384.     {
  385.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  386.     /* Turn on all card status change interrupts */
  387.     pcicSet (sock, PCIC_CSCINT, (irq << 4) | PCIC_CSC_ANY);
  388.     pcicBclr (sock, PCIC_INTCTL, PCIC_INTR_ENA);
  389.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  390.     return (OK);
  391.     }
  392. /*******************************************************************************
  393. *
  394. * pcicCscOff - Disable the card status change interrupt.
  395. *
  396. * This routine Disables the card status change interrupt.
  397. *
  398. * RETURNS: OK (always).
  399. */
  400. LOCAL STATUS pcicCscOff
  401.     (
  402.     int sock, /* socket no. */
  403.     int irq /* IRQ level for CSC */
  404.     )
  405.     {
  406.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  407.     /* Turn off all card status change interrupts */
  408.     pcicSet (sock, PCIC_CSCINT, (irq << 4) | 0x00);
  409.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  410.     return (OK);
  411.     }
  412. /*******************************************************************************
  413. *
  414. * pcicCscPoll - Get the card status by polling the register.
  415. *
  416. * This routine gets the card status by polling the register.
  417. * This routine can be called in interrupt level.
  418. *
  419. * RETURNS: The card status of the socket.
  420. */
  421. LOCAL int pcicCscPoll
  422.     (
  423.     int sock /* socket no. */
  424.     )
  425.     {
  426.     BOOL intMode = intContext ();
  427.     int  value;
  428.     int  value0;
  429.     int  status;
  430.     if (!intMode)
  431.         semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  432.     value = pcicGet (sock, PCIC_CSC);
  433.     while ((value0 = pcicGet (sock, PCIC_CSC)) != 0)
  434.         value |= value0;
  435.     if (pcicGet (sock, PCIC_INTCTL) & PCIC_PC_IOCARD)
  436. status  = (value & PCIC_CSC_STSCHG) ? PC_STSCHG : 0;
  437.     else
  438. {
  439. status  = (value & PCIC_CSC_BVD1) ? PC_BATDEAD : 0;
  440. status |= (value & PCIC_CSC_BVD2) ? PC_BATWARN : 0;
  441.         }
  442.     status |= (value & PCIC_CSC_READY) ? PC_READY : 0;
  443.     status |= (value & PCIC_CSC_DETECT) ? PC_DETECT : 0;
  444.     if (!intMode)
  445.         semGive (&pcicMuteSem);   /* mutual execlusion stop */
  446.     return (status);
  447.     }
  448. /*******************************************************************************
  449. *
  450. * pcicIrqGet - Get IRQ level of the socket.
  451. *
  452. * This routine gets IRQ level of the socket.
  453. *
  454. * RETURNS: The IRQ level of the socket.
  455. */
  456. LOCAL int pcicIrqGet
  457.     (
  458.     int sock /* socket no. */
  459.     )
  460.     {
  461.     char value;
  462.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  463.     value = pcicGet (sock, PCIC_INTCTL);
  464.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  465.     return (value & PCIC_IRQ_MASK);
  466.     }
  467. /*******************************************************************************
  468. *
  469. * pcicIrqSet - Set IRQ level of the socket.
  470. *
  471. * This routine sets IRQ level of the socket.
  472. *
  473. * RETURNS: OK, or ERROR if the IRQ level is greater than 15.
  474. */
  475. LOCAL STATUS pcicIrqSet
  476.     (
  477.     int sock, /* socket no. */
  478.     int irq /* IRQ level for the PC card */
  479.     )
  480.     {
  481.     char value;
  482.     if (irq > 15)
  483. return (ERROR);
  484.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  485.     value = pcicGet (sock, PCIC_INTCTL);
  486.     value = (value & ~PCIC_IRQ_MASK) | irq;
  487.     pcicSet (sock, PCIC_INTCTL, value);
  488.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  489.     return (OK);
  490.     }
  491. /*******************************************************************************
  492. *
  493. * pcicReset - Reset a card in the socket.
  494. *
  495. * This routine reset a card in the socket.
  496. *
  497. * RETURNS: OK (always).
  498. */
  499. LOCAL STATUS pcicReset
  500.     (
  501.     int sock /* socket no. */
  502.     )
  503.     {
  504.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  505.     /* Turn off interrupts, select memory-only interface */
  506.     pcicBclr (sock, PCIC_INTCTL, PCIC_PC_IOCARD | PCIC_IRQ_MASK);
  507.     /* Turn off all IO and Memory windows */
  508.     pcicBclr (sock, PCIC_ADDRWIN, PCIC_ENA_ALL);
  509.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  510.     return (OK);
  511.     }
  512. /*******************************************************************************
  513. *
  514. * pcicIowinGet - Get the IO window of the socket.
  515. *
  516. * This routine gets the IO window of the socket.
  517. *
  518. * RETURNS: OK, or ERROR if the window number is greater than max windows.
  519. */
  520. LOCAL STATUS pcicIowinGet
  521.     (
  522.     int  sock, /* socket no. */
  523.     PCMCIA_IOWIN *io /* io window structure to get */
  524.     )
  525.     {
  526.     char window = io->window;
  527.     char ioctl;
  528.     char addr;
  529.     if (window >= PCIC_IO_WINDOWS)
  530. return (ERROR);
  531.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  532.     ioctl = pcicGet (sock, PCIC_IOCTL);
  533.     addr = pcicGet (sock, PCIC_ADDRWIN);
  534.     io->start = pcicGet2 (sock, PCIC_IO(window)+PCIC_W_START);
  535.     io->stop = pcicGet2 (sock, PCIC_IO(window)+PCIC_W_STOP);
  536.     io->extraws = (ioctl & PCIC_IOCTL_WAIT(window)) ? 1 : 0;
  537.     io->flags = (addr & PCIC_ENA_IO(window)) ? MAP_ACTIVE : 0;
  538.     io->flags  |= (ioctl & PCIC_IOCTL_0WS(window)) ? MAP_0WS : 0;
  539.     io->flags  |= (ioctl & PCIC_IOCTL_CS16(window)) ? MAP_CS16 : 0;
  540.     io->flags  |= (ioctl & PCIC_IOCTL_16BIT(window)) ? MAP_16BIT : 0;
  541.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  542.     return (OK);
  543.     }
  544. /*******************************************************************************
  545. *
  546. * pcicIowinSet - Set the IO window of the socket.
  547. *
  548. * This routine sets the IO window of the socket.
  549. *
  550. * RETURNS: OK, or ERROR if there is an error.
  551. */
  552. LOCAL STATUS pcicIowinSet
  553.     (
  554.     int  sock, /* socket no. */
  555.     PCMCIA_IOWIN *io /* io window structure to set */
  556.     )
  557.     {
  558.     char window = io->window;
  559.     char ioctl;
  560.     if ((window >= PCIC_IO_WINDOWS) || (io->start > 0xffff) ||
  561. (io->stop > 0xffff) || (io->stop < io->start))
  562. return (ERROR);
  563.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  564.     ioctl = pcicGet (sock, PCIC_IOCTL) & ~PCIC_IOCTL_MASK(window);
  565.     /* Turn off the window before changing anything */
  566.     if (pcicGet (sock, PCIC_ADDRWIN) & PCIC_ENA_IO(window))
  567. pcicBclr (sock, PCIC_ADDRWIN, PCIC_ENA_IO(window));
  568.     pcicSet2 (sock, PCIC_IO(window)+PCIC_W_START, io->start);
  569.     pcicSet2 (sock, PCIC_IO(window)+PCIC_W_STOP, io->stop);
  570.     if (io->extraws) 
  571. ioctl |= PCIC_IOCTL_WAIT(window);
  572.     if (io->flags & MAP_0WS) 
  573. ioctl |= PCIC_IOCTL_0WS(window);
  574.     if (io->flags & MAP_CS16) 
  575. ioctl |= PCIC_IOCTL_CS16(window);
  576.     if (io->flags & MAP_16BIT) 
  577. ioctl |= PCIC_IOCTL_16BIT(window);
  578.     pcicSet (sock, PCIC_IOCTL, ioctl);
  579.     /* Turn on the window if necessary */
  580.     if (io->flags & MAP_ACTIVE)
  581. pcicBset (sock, PCIC_ADDRWIN, PCIC_ENA_IO(window));
  582.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  583.     return (OK);
  584.     }
  585. /*******************************************************************************
  586. *
  587. * pcicMemwinGet - Get the Memory window of the socket.
  588. *
  589. * This routine gets the Memory window of the socket.
  590. *
  591. * RETURNS: OK, or ERROR if the window number is greater than max windows.
  592. */
  593. LOCAL STATUS pcicMemwinGet
  594.     (
  595.     int   sock, /* socket no. */
  596.     PCMCIA_MEMWIN *mem /* memory window structure to get */
  597.     )
  598.     {
  599.     char window = mem->window;
  600.     char addr;
  601.     short base;
  602.     short value;
  603.     
  604.     if (window >= PCIC_MEM_WINDOWS)
  605. return (ERROR);
  606.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  607.     addr     = pcicGet (sock, PCIC_ADDRWIN);
  608.     base     = PCIC_MEM(window);
  609.     mem->flags     = (addr & PCIC_ENA_MEM(window)) ? MAP_ACTIVE : 0;
  610.     
  611.     value = pcicGet2 (sock, base+PCIC_W_START);
  612.     mem->flags     |= (value & PCIC_MEM_16BIT) ? MAP_16BIT : 0;
  613.     mem->flags     |= (value & PCIC_MEM_0WS) ? MAP_0WS : 0;
  614.     mem->start      = ((long)(value & 0x0fff) << 12);
  615.     
  616.     value = pcicGet2 (sock, base+PCIC_W_STOP);
  617.     mem->extraws    = (value & PCIC_MEM_WS0) ? 1 : 0;
  618.     mem->extraws   += (value & PCIC_MEM_WS1) ? 2 : 0;
  619.     mem->stop     = ((long)(value & 0x0fff) << 12) + 0x0fff;
  620.     
  621.     value = pcicGet2 (sock, base+PCIC_W_OFF);
  622.     mem->flags    |= (value & PCIC_MEM_WRPROT) ? MAP_WRPROT : 0;
  623.     mem->flags    |= (value & PCIC_MEM_REG) ? MAP_ATTRIB : 0;
  624.     mem->cardstart  = ((long)(value & 0x3fff) << 12) + mem->start;
  625.     mem->cardstart &= 0x3ffffff;
  626.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  627.     return (OK);
  628.     }
  629. /*******************************************************************************
  630. *
  631. * pcicMemwinSet - Set the Memory window of the socket.
  632. *
  633. * This routine sets the Memory window of the socket.
  634. *
  635. * RETURNS: OK, or ERROR if there is an error.
  636. */
  637. LOCAL STATUS pcicMemwinSet
  638.     (
  639.     int   sock, /* socket no. */
  640.     PCMCIA_MEMWIN *mem /* memory window structure to set */
  641.     )
  642.     {
  643.     char window = mem->window;
  644.     short base;
  645.     short value;
  646.     
  647.     if ((window >= PCIC_MEM_WINDOWS) || (mem->cardstart > 0x3ffffff) ||
  648. (mem->start > 0xffffff) || (mem->stop > 0xffffff) ||
  649. (mem->start > mem->stop) || (mem->extraws > 3))
  650. return (ERROR);
  651.     semTake (&pcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  652.     base = PCIC_MEM(window);
  653.     /* Turn off the window before changing anything */
  654.     if (pcicGet (sock, PCIC_ADDRWIN) & PCIC_ENA_MEM(window))
  655. pcicBclr (sock, PCIC_ADDRWIN, PCIC_ENA_MEM(window));
  656.     
  657.     value = mem->start >> 12;
  658.     if (mem->flags & MAP_16BIT)
  659. {
  660. value |= PCIC_MEM_16BIT;
  661. pcicBset (sock, PCIC_ADDRWIN, PCIC_ENA_MEMCS16);
  662. }
  663.     if (mem->flags & MAP_0WS)
  664. value |= PCIC_MEM_0WS;
  665.     pcicSet2 (sock, base+PCIC_W_START, value);
  666.     
  667.     value = mem->stop >> 12;
  668.     if (mem->extraws & 1)
  669. value |= PCIC_MEM_WS0;
  670.     if (mem->extraws & 2)
  671. value |= PCIC_MEM_WS1;
  672.     pcicSet2 (sock, base+PCIC_W_STOP, value);
  673.     
  674.     value = ((mem->cardstart - mem->start) >> 12) & 0x3fff;
  675.     if (mem->flags & MAP_WRPROT)
  676. value |= PCIC_MEM_WRPROT;
  677.     if (mem->flags & MAP_ATTRIB)
  678. value |= PCIC_MEM_REG;
  679.     pcicSet2 (sock, base+PCIC_W_OFF, value);
  680.     
  681.     /* Turn on the window if necessary */
  682.     if (mem->flags & MAP_ACTIVE)
  683. pcicBset (sock, PCIC_ADDRWIN, PCIC_ENA_MEM(window));
  684.     semGive (&pcicMuteSem);   /* mutual execlusion stop */
  685.     return (OK);
  686.     }
  687. /*******************************************************************************
  688. *
  689. * pcicGet - Get a value from the register.
  690. *
  691. * This routine gets a value from the register.
  692. *
  693. * RETURNS: A value of the register.
  694. */
  695. LOCAL int pcicGet
  696.     (
  697.     int sock, /* socket no. */
  698.     int reg /* register no. */
  699.     )
  700.     {
  701.     short port = PCIC_PORT (sock);
  702.     char offset = PCIC_REG (sock, reg);
  703.     sysOutByte (port, offset);
  704.     return (sysInByte (port+1));
  705.     }
  706. /*******************************************************************************
  707. *
  708. * pcicSet - Set a value into the register.
  709. *
  710. * This routine sets a value into the register.
  711. *
  712. * RETURNS: N/A
  713. */
  714. LOCAL void pcicSet
  715.     (
  716.     int  sock, /* socket no. */
  717.     int  reg, /* register no. */
  718.     char value /* value to set */
  719.     )
  720.     {
  721.     short port = PCIC_PORT (sock);
  722.     char offset = PCIC_REG (sock, reg);
  723.     sysOutByte (port, offset);
  724.     sysOutByte (port+1, value);
  725.     }
  726. /*******************************************************************************
  727. *
  728. * pcicBset - Set specified bits in the register.
  729. *
  730. * This routine sets specified bits in the register.
  731. *
  732. * RETURNS: N/A
  733. */
  734. LOCAL void pcicBset
  735.     (
  736.     int  sock, /* socket no. */
  737.     int  reg, /* register no. */
  738.     char mask /* bits to set */
  739.     )
  740.     {
  741.     char value = pcicGet (sock, reg);
  742.     value |= mask;
  743.     pcicSet (sock, reg, value);
  744.     }
  745. /*******************************************************************************
  746. *
  747. * pcicBclr - Clear specified bits in the register.
  748. *
  749. * This routine clears specified bits in the register.
  750. *
  751. * RETURNS: N/A
  752. */
  753. LOCAL void pcicBclr
  754.     (
  755.     int  sock, /* socket no. */
  756.     int  reg, /* register no. */
  757.     char mask /* bits to clear */
  758.     )
  759.     {
  760.     char value = pcicGet (sock, reg);
  761.     value &= ~mask;
  762.     pcicSet (sock, reg, value);
  763.     }
  764. /*******************************************************************************
  765. *
  766. * pcicGet2 - Get a value from the consecutive registers.
  767. *
  768. * This routine gets a value from the consecutive registers.
  769. *
  770. * RETURNS: a value of the register
  771. */
  772. LOCAL int pcicGet2
  773.     (
  774.     int sock, /* socket no. */
  775.     int reg /* register no. */
  776.     )
  777.     {
  778.     short a = pcicGet (sock, reg);
  779.     short b = pcicGet (sock, reg+1);
  780.     return (a + (b<<8));
  781.     }
  782. /*******************************************************************************
  783. *
  784. * pcicSet2 - Set a value into the consecutive registers.
  785. *
  786. * This routine sets a value into the consecutive registers.
  787. *
  788. * RETURNS: N/A
  789. */
  790. LOCAL void pcicSet2
  791.     (
  792.     int   sock, /* socket no. */
  793.     int   reg, /* register no. */
  794.     short value /* value to set */
  795.     )
  796.     {
  797.     pcicSet (sock, reg, value & 0xff);
  798.     pcicSet (sock, reg+1, value >> 8);
  799.     }