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

VxWorks

开发平台:

C/C++

  1. /* tcic.c - Databook TCIC/2 PCMCIA host bus adaptor chip driver */
  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. 01f,21jun00,rsh  upgrade to dosFs 2.0
  9. 01e,29mar96,jdi  doc: fixed error.
  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,03oct95,hdn  written based on David Hinds's version 2.2.3.
  14. */
  15. /*
  16. DESCRIPTION
  17. This library contains routines to manipulate the PCMCIA functions on the
  18. Databook DB86082 PCMCIA chip.  
  19. The initialization routine tcicInit() is the only global function and is
  20. included in the PCMCIA chip table `pcmciaAdapter'.  If tcicInit() finds
  21. the TCIC chip, it registers all function pointers of the PCMCIA_CHIP
  22. structure.
  23. */
  24. #include "vxWorks.h"
  25. #include "taskLib.h"
  26. #include "intLib.h"
  27. #include "sysLib.h"
  28. #include "drv/pcmcia/pcmciaLib.h"
  29. #include "drv/pcmcia/tcic.h"
  30. /* defines */
  31. #define TCIC_GETB(reg) sysInByte  (tcicBase+reg)
  32. #define TCIC_GETW(reg) sysInWord  (tcicBase+reg)
  33. #define TCIC_SETB(reg, value) sysOutByte (tcicBase+reg, value)
  34. #define TCIC_SETW(reg, value) sysOutWord (tcicBase+reg, value)
  35. /* imports */
  36. IMPORT PCMCIA_CTRL pcmciaCtrl;
  37. /* globals */
  38. int tcicBase;
  39. /* locals */
  40. LOCAL char tcicCardStatus[TCIC_MAX_SOCKS];
  41. LOCAL SEMAPHORE tcicMuteSem;
  42. /* forward declarations */
  43. LOCAL STATUS tcicReset (int sock);
  44. LOCAL int tcicStatus (int sock);
  45. LOCAL int tcicFlagGet (int sock);
  46. LOCAL STATUS tcicFlagSet (int sock, int flag);
  47. LOCAL STATUS tcicCscOn (int sock, int irq);
  48. LOCAL STATUS tcicCscOff (int sock, int irq);
  49. LOCAL int tcicCscPoll (int sock);
  50. LOCAL int tcicIrqGet (int sock);
  51. LOCAL STATUS tcicIrqSet (int sock, int irq);
  52. LOCAL STATUS tcicIowinGet (int sock, PCMCIA_IOWIN *io);
  53. LOCAL STATUS tcicIowinSet (int sock, PCMCIA_IOWIN *io);
  54. LOCAL STATUS tcicMemwinGet (int sock, PCMCIA_MEMWIN *mem);
  55. LOCAL STATUS tcicMemwinSet (int sock, PCMCIA_MEMWIN *mem);
  56. LOCAL char tcicAuxGetb (int reg);
  57. LOCAL void tcicAuxSetb (int reg, char value);
  58. #ifdef __unused__
  59. LOCAL short tcicAuxGetw (int reg);
  60. #endif
  61. LOCAL void tcicAuxSetw (int reg, short value);
  62. LOCAL long tcicGetl (int reg);
  63. LOCAL void tcicSetl (int reg, long value);
  64. /*******************************************************************************
  65. *
  66. * tcicInit - initialize the TCIC chip
  67. *
  68. * This routine initializes the TCIC chip.
  69. *
  70. * RETURNS: OK, or ERROR if the TCIC chip cannot be found.
  71. */
  72. STATUS tcicInit
  73.     (
  74.     int     ioBase, /* IO base address */
  75.     int     intVec, /* interrupt vector */
  76.     int     intLevel, /* interrupt level */
  77.     FUNCPTR showRtn /* show routine */
  78.     )
  79.     {
  80.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  81.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  82.     int sock = 0;
  83.     int ix;
  84.     tcicBase = ioBase;
  85.     TCIC_SETW (TCIC_ADDR, 0);
  86.     if (TCIC_GETW (TCIC_ADDR) == 0)
  87. {
  88. TCIC_SETW (TCIC_ADDR, 0xc3a5);
  89. if (TCIC_GETW (TCIC_ADDR) == 0xc3a5)
  90.     sock = 2;
  91. }
  92.     
  93.     if (sock == 0)
  94. return (ERROR);
  95.     
  96.     semMInit (&tcicMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE | 
  97.       SEM_INVERSION_SAFE);
  98.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  99.     tcicAuxSetb (TCIC_AUX_WCTL, TCIC_WAIT_SENSE | TCIC_WAIT_ASYNC | 7);
  100.     tcicAuxSetw (TCIC_AUX_SYSCFG, TCIC_SYSCFG_AUTOBUSY | 0x0a00);
  101.     for (ix = 0; ix < sock; ix++)
  102. {
  103.         tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) | 
  104.   TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  105.         tcicAuxSetb (TCIC_AUX_ILOCK, TCIC_ILOCK_HOLD_CCLK | TCIC_ILOCK_CWAIT |
  106.      TCIC_ILOCK_CRESENA);
  107.         tcicCardStatus[sock] = TCIC_GETB (TCIC_SSTAT);
  108. }
  109.     pChip->name = "Databook TCIC2";
  110.     pChip->reset = (FUNCPTR) tcicReset;
  111.     pChip->status = (FUNCPTR) tcicStatus;
  112.     pChip->flagGet = (FUNCPTR) tcicFlagGet;
  113.     pChip->flagSet = (FUNCPTR) tcicFlagSet;
  114.     pChip->cscOn = (FUNCPTR) tcicCscOn;
  115.     pChip->cscOff = (FUNCPTR) tcicCscOff;
  116.     pChip->cscPoll = (FUNCPTR) tcicCscPoll;
  117.     pChip->irqGet = (FUNCPTR) tcicIrqGet;
  118.     pChip->irqSet = (FUNCPTR) tcicIrqSet;
  119.     pChip->iowinGet = (FUNCPTR) tcicIowinGet;
  120.     pChip->iowinSet = (FUNCPTR) tcicIowinSet;
  121.     pChip->memwinGet = (FUNCPTR) tcicMemwinGet;
  122.     pChip->memwinSet = (FUNCPTR) tcicMemwinSet;
  123.     pChip->type = PCMCIA_TCIC;
  124.     pChip->socks = sock;
  125.     pChip->installed = TRUE;
  126.     pChip->intLevel = intLevel;
  127.     pChip->memWindows = TCIC_MEM_WINDOWS;
  128.     pChip->ioWindows = TCIC_IO_WINDOWS;
  129.     pChip->showRtn = showRtn;
  130.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  131.     return (OK);
  132.     }
  133. /*******************************************************************************
  134. *
  135. * tcicStatus - Get status of the socket.
  136. *
  137. * This routine gets status of the socket.
  138. * This routine can be called in interrupt level.
  139. *
  140. * RETURNS: The status of the socket.
  141. */
  142. LOCAL int tcicStatus
  143.     (
  144.     int sock /* socket no. */
  145.     )
  146.     {
  147.     BOOL intMode = intContext ();
  148.     int valueAddr = 0;
  149.     char value;
  150.     int status;
  151.     if (intMode)
  152. valueAddr = tcicGetl (TCIC_ADDR);
  153.     else
  154.         semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  155.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT)
  156.       | TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  157.     value = TCIC_GETB (TCIC_SSTAT);
  158.     status  = (value & TCIC_SSTAT_CD) ? PC_IS_CARD : PC_NO_CARD;
  159.     status |= (value & TCIC_SSTAT_WP) ? PC_WRPROT : 0;
  160.     if (TCIC_GETW (TCIC_DATA) & TCIC_SCF1_IOSTS)
  161. status |= (value & TCIC_SSTAT_LBAT1) ? PC_STSCHG : 0;
  162.     else
  163. {
  164. status |= (value & TCIC_SSTAT_RDY) ? PC_READY : 0;
  165. status |= (value & TCIC_SSTAT_LBAT1) ? PC_BATDEAD : 0;
  166. status |= (value & TCIC_SSTAT_LBAT2) ? PC_BATWARN : 0;
  167.         }
  168.     value = TCIC_GETB (TCIC_PWR);
  169.     if (value & (TCIC_PWR_VCC (sock) | TCIC_PWR_VPP (sock)))
  170. status |= PC_POWERON;
  171.     if (intMode)
  172. tcicSetl (TCIC_ADDR, valueAddr);
  173.     else
  174.         semGive (&tcicMuteSem);   /* mutual execlusion stop */
  175.     return (status);
  176.     }
  177.   
  178. /*******************************************************************************
  179. *
  180. * tcicFlagGet - Get configuration flag from the socket.
  181. *
  182. * This routine gets configuration flag from the socket.
  183. *
  184. * RETURNS: The configuration flag of the socket.
  185. */
  186. LOCAL int tcicFlagGet
  187.     (
  188.     int sock /* socket no. */
  189.     )
  190.     {
  191.     short value;
  192.     int flag;
  193.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  194.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) |
  195.       TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  196.     flag = (TCIC_GETW (TCIC_DATA) & TCIC_SCF1_IOSTS) ? PC_IOCARD : 0;
  197.     value = TCIC_GETB (TCIC_PWR);
  198.     if (value & TCIC_PWR_VCC (sock))
  199. {
  200. if (value & TCIC_PWR_VPP (sock))
  201.     flag |= PC_VCC_5V;
  202. else
  203.     flag |= PC_VCC_5V | PC_VPP_5V;
  204. }
  205.     else
  206. if (value & TCIC_PWR_VPP (sock))
  207.     flag |= PC_VCC_5V | PC_VPP_12V;
  208.     value = tcicAuxGetb (TCIC_AUX_ILOCK);
  209.     flag |= (value & TCIC_ILOCK_CRESET) ? PC_RESET : 0;
  210.     
  211.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  212.     return (flag);
  213.     }
  214. /*******************************************************************************
  215. *
  216. * tcicFlagSet - Set configuration flag into the socket.
  217. *
  218. * This routine sets configuration flag into the socket.
  219. *
  220. * RETURNS: OK (always).
  221. */
  222. LOCAL STATUS tcicFlagSet
  223.     (
  224.     int sock, /* socket no. */
  225.     int flag /* configuration flag */
  226.     )
  227.     {
  228.     char value;
  229.     short scf1;
  230.     short scf2;
  231.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  232.     TCIC_SETW (TCIC_ADDR+2, (sock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
  233.     value = TCIC_GETB (TCIC_PWR);
  234.     value &= ~(TCIC_PWR_VCC (sock) | TCIC_PWR_VPP (sock));
  235.     if (flag & PC_VCC_5V)
  236. {
  237. if (flag & PC_VPP_12V)
  238.     value |= TCIC_PWR_VPP (sock);
  239. else if (flag & PC_VPP_5V)
  240.     value |= TCIC_PWR_VCC (sock);
  241. else
  242.     value |= TCIC_PWR_VCC (sock) | TCIC_PWR_VPP (sock);
  243.         }
  244.     TCIC_SETB (TCIC_PWR, value);
  245.     taskDelay (sysClkRateGet () >> 4);
  246.     TCIC_SETW (TCIC_ADDR, TCIC_SCF1 (sock));
  247.     scf1 = TCIC_GETW (TCIC_DATA);
  248.     TCIC_SETW (TCIC_ADDR, TCIC_SCF2 (sock));
  249.     scf2 = TCIC_GETW (TCIC_DATA);
  250.     if (flag & PC_IOCARD) 
  251. {
  252. scf1 |= TCIC_SCF1_IOSTS | TCIC_SCF1_SPKR;
  253. scf2 |= TCIC_SCF2_MRDY;
  254.         }
  255.     else
  256. {
  257. scf1 &= ~(TCIC_SCF1_IOSTS | TCIC_SCF1_SPKR);
  258. scf2 &= ~TCIC_SCF2_MRDY;
  259.         }
  260.     TCIC_SETW (TCIC_ADDR, TCIC_SCF1 (sock));
  261.     TCIC_SETW (TCIC_DATA, scf1);
  262.     TCIC_SETW (TCIC_ADDR, TCIC_SCF2 (sock));
  263.     TCIC_SETW (TCIC_DATA, scf2);
  264.     if (flag & PC_VCC_MASK)
  265. TCIC_SETB (TCIC_SCTRL, TCIC_SCTRL_ENA);
  266.     value = tcicAuxGetb (TCIC_AUX_ILOCK) & ~TCIC_ILOCK_CRESET;
  267.     if (flag & PC_RESET)
  268. value |= TCIC_ILOCK_CRESET;
  269.     tcicAuxSetb (TCIC_AUX_ILOCK, value);
  270.     
  271.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  272.     return (OK);
  273.     }
  274.   
  275. /*******************************************************************************
  276. *
  277. * tcicCscOn - Enables card status change interrupt.
  278. *
  279. * This routine enables card status change interrupt.
  280. *
  281. * RETURNS: OK (always).
  282. */
  283. LOCAL STATUS tcicCscOn
  284.     (
  285.     int sock, /* socket no. */
  286.     int irq /* IRQ for CSC */
  287.     )
  288.     {
  289.     char value;
  290.     short scf2;
  291.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  292.     /* Turn on all card status change interrupts */
  293.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) | 
  294.       TCIC_ADDR_INDREG | TCIC_SCF2(sock));
  295.     value = tcicAuxGetb (TCIC_AUX_SYSCFG);
  296.     tcicAuxSetb (TCIC_AUX_SYSCFG, value | irq);
  297.     TCIC_SETB (TCIC_IENA, TCIC_IENA_CDCHG | TCIC_IENA_CFG_HIGH);
  298.     scf2 = TCIC_GETW (TCIC_DATA);
  299.     scf2 &= TCIC_SCF2_MDBR | TCIC_SCF2_IDBR | TCIC_SCF2_RI;
  300.     TCIC_SETW (TCIC_DATA, scf2);
  301.     /* flush current card status changes */
  302.     TCIC_SETB (TCIC_ICSR, TCIC_ICSR_CLEAR);
  303.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  304.     return (OK);
  305.     }
  306. /*******************************************************************************
  307. *
  308. * tcicCscOff - Disable card status change interrupt.
  309. *
  310. * This routine disables card status change interrupt.
  311. *
  312. * RETURNS: OK (always).
  313. */
  314. LOCAL STATUS tcicCscOff
  315.     (
  316.     int sock, /* socket no. */
  317.     int irq /* IRQ for CSC */
  318.     )
  319.     {
  320.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  321.     TCIC_SETW (TCIC_ADDR+2, (sock << TCIC_SS_SHFT));
  322.     TCIC_SETB (TCIC_IENA, TCIC_IENA_CFG_OFF);
  323.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  324.     return (OK);
  325.     }
  326. /*******************************************************************************
  327. *
  328. * tcicCscPoll - Get the card status by polling the register.
  329. *
  330. * This routine gets the card status by polling the register.
  331. * This routine can be called in interrupt level.
  332. *
  333. * RETURNS: The card status of the socket.
  334. */
  335. LOCAL int tcicCscPoll
  336.     (
  337.     int sock /* socket no. */
  338.     )
  339.     {
  340.     char latch  = 0;
  341.     BOOL intMode = intContext ();
  342.     char value;
  343.     int  status;
  344.     int  ix;
  345.     int  valueAddr = 0;
  346.     
  347.     if (intMode)
  348. valueAddr = tcicGetl (TCIC_ADDR);
  349.     else
  350.         semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  351.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) |
  352.       TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  353.     for (ix = 0; ix < 10; ix++)
  354. {
  355. /* What bits have changed state? */
  356. value = TCIC_GETB (TCIC_SSTAT);
  357. latch |= value ^ tcicCardStatus[sock];
  358. tcicCardStatus[sock] = value;
  359. /* Try to reset interrupt status register */
  360. if (TCIC_GETB (TCIC_ICSR) != 0)
  361.     TCIC_SETB (TCIC_ICSR, TCIC_ICSR_CLEAR);
  362. else
  363.     break;
  364.         }
  365.     status  = (latch & TCIC_SSTAT_CD) ? PC_DETECT : 0;
  366.     status |= (latch & TCIC_SSTAT_WP) ? PC_WRPROT : 0;
  367.     if (TCIC_GETW (TCIC_DATA) & TCIC_SCF1_IOSTS)
  368. status |= (latch & TCIC_SSTAT_LBAT1) ? PC_STSCHG : 0;
  369.     else
  370. {
  371. status |= (latch & TCIC_SSTAT_RDY)   ? PC_READY : 0;
  372. status |= (latch & TCIC_SSTAT_LBAT1) ? PC_BATDEAD : 0;
  373. status |= (latch & TCIC_SSTAT_LBAT2) ? PC_BATWARN : 0;
  374.         }
  375.     if (intMode)
  376. tcicSetl (TCIC_ADDR, valueAddr);
  377.     else
  378.         semGive (&tcicMuteSem);   /* mutual execlusion stop */
  379.     return (status);
  380.     }
  381. /*******************************************************************************
  382. *
  383. * tcicIrqGet - Get IRQ level of the socket.
  384. *
  385. * This routine gets IRQ level of the socket.
  386. *
  387. * RETURNS: The IRQ level of the socket.
  388. */
  389. LOCAL int tcicIrqGet
  390.     (
  391.     int sock /* socket no. */
  392.     )
  393.     {
  394.     int value;
  395.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  396.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) |
  397.       TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  398.     value = TCIC_GETW (TCIC_DATA) & 0x0f;
  399.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  400.     return (value);
  401.     }
  402.   
  403. /*******************************************************************************
  404. *
  405. * tcicIrqSet - Set IRQ level of the socket.
  406. *
  407. * This routine sets IRQ level of the socket.
  408. *
  409. * RETURNS: OK, or ERROR if the IRQ level is greater than 15.
  410. */
  411. LOCAL STATUS tcicIrqSet
  412.     (
  413.     int sock, /* socket no. */
  414.     int irq /* IRQ for PC card */
  415.     )
  416.     {
  417.     short scf1;
  418.     
  419.     if (irq > 15)
  420. return (ERROR);
  421.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  422.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) |
  423.       TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  424.     
  425.     scf1 = TCIC_GETW (TCIC_DATA);
  426.     scf1 &= ~(TCIC_SCF1_IRQOC | TCIC_SCF1_IRQ_MASK);
  427.     scf1 |= irq;
  428.     TCIC_SETW (TCIC_DATA, scf1);
  429.     
  430.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  431.     return (OK);
  432.     }
  433. /*******************************************************************************
  434. *
  435. * tcicReset - Reset a card in the socket.
  436. *
  437. * This routine resets a card in the socket.
  438. *
  439. * RETURNS: OK (always).
  440. */
  441. LOCAL STATUS tcicReset
  442.     (
  443.     int sock /* socket no. */
  444.     )
  445.     {
  446.     int ix;
  447.     short value;
  448.     
  449.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  450.     /* Turn off interrupts, select memory-only interface */
  451.     tcicSetl (TCIC_ADDR, (sock << TCIC_ADDR_SS_SHFT) |
  452.       TCIC_ADDR_INDREG | TCIC_SCF1(sock));
  453.     value = TCIC_GETW (TCIC_DATA);
  454.     value &= ~(TCIC_SCF1_IRQ_MASK | TCIC_SCF1_IOSTS);
  455.     TCIC_SETW (TCIC_DATA, value);
  456.     
  457.     /* Reset event mask, since we've turned off I/O mode */
  458.     TCIC_SETW (TCIC_ADDR, TCIC_SCF2(sock));
  459.     value = TCIC_GETW (TCIC_DATA);
  460.     value &= TCIC_SCF2_MDBR | TCIC_SCF2_IDBR | TCIC_SCF2_RI;
  461.     TCIC_SETW (TCIC_DATA, value);
  462.     
  463.     /* Turn off I/O windows */
  464.     for (ix = 0; ix < 2; ix++)
  465. {
  466. TCIC_SETW (TCIC_ADDR, TCIC_IWIN(sock, ix) + TCIC_ICTL_X);
  467. TCIC_SETW (TCIC_DATA, 0);
  468.         }
  469.     
  470.     /* Turn off memory windows */
  471.     for (ix = 0; ix < 4; ix++)
  472. {
  473. TCIC_SETW (TCIC_ADDR, TCIC_MWIN(sock, ix) + TCIC_MCTL_X);
  474. TCIC_SETW (TCIC_DATA, 0);
  475.         }
  476.     
  477.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  478.     return (OK);
  479.     }
  480. /*******************************************************************************
  481. *
  482. * tcicIowinGet - Get the IO window of the socket.
  483. *
  484. * This routine gets the IO window of the socket.
  485. *
  486. * RETURNS: OK, or ERROR if the window number is greater than max windows.
  487. */
  488. LOCAL STATUS tcicIowinGet
  489.     (
  490.     int  sock, /* socket no. */
  491.     PCMCIA_IOWIN *io /* IO window structure to get */
  492.     )
  493.     {
  494.     short base;
  495.     short ioctl;
  496.     long  addr;
  497.     
  498.     if (io->window >= TCIC_IO_WINDOWS)
  499. return (ERROR);
  500.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  501.     TCIC_SETW (TCIC_ADDR+2, TCIC_ADR2_INDREG | (sock << TCIC_SS_SHFT));
  502.     addr = TCIC_IWIN(sock, io->window);
  503.     TCIC_SETW (TCIC_ADDR, addr + TCIC_IBASE_X);
  504.     base = TCIC_GETW (TCIC_DATA);
  505.     TCIC_SETW (TCIC_ADDR, addr + TCIC_ICTL_X);
  506.     ioctl = TCIC_GETW (TCIC_DATA);
  507.     if (ioctl & TCIC_ICTL_TINY)
  508. io->start = io->stop = base;
  509.     else
  510. {
  511. io->start = base & (base-1);
  512. io->stop = io->start + (base ^ (base-1));
  513.         }
  514.     io->extraws = ioctl & TCIC_ICTL_WSCNT_MASK;
  515.     io->flags = (ioctl & TCIC_ICTL_ENA) ? MAP_ACTIVE : 0;
  516.     if ((ioctl & TCIC_ICTL_BW_MASK) == TCIC_ICTL_BW_16)
  517. io->flags |= MAP_16BIT;
  518.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  519.     return (OK);
  520.     }
  521. /*******************************************************************************
  522. *
  523. * tcicIowinSet - Set the IO window of the socket.
  524. *
  525. * This routine sets the IO window of the socket.
  526. *
  527. * RETURNS: OK, or ERROR if there is an error.
  528. */
  529. LOCAL STATUS tcicIowinSet
  530.     (
  531.     int  sock, /* socket no. */
  532.     PCMCIA_IOWIN *io /* IO window structure to set */
  533.     )
  534.     {
  535.     long addr;
  536.     int base;
  537.     int len;
  538.     int ix;
  539.     short ioctl;
  540.     
  541.     if ((io->window >= TCIC_IO_WINDOWS) || (io->start > 0xffff) ||
  542. (io->stop > 0xffff) || (io->stop < io->start))
  543. return (ERROR);
  544.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  545.     TCIC_SETW (TCIC_ADDR+2, TCIC_ADR2_INDREG | (sock << TCIC_SS_SHFT));
  546.     addr = TCIC_IWIN(sock, io->window);
  547.     base = io->start;
  548.     len  = io->stop - io->start + 1;
  549.     /* adject base address according to the length */
  550.     for (ix = 0; ix < 16; ix++)
  551. if ((1 << ix) >= len)
  552.     break;
  553.     if (len != 1)
  554. {
  555. base &= ~((1 << ix) - 1);
  556. base += 1 << (ix - 1);
  557. }
  558.     TCIC_SETW (TCIC_ADDR, addr + TCIC_IBASE_X);
  559.     TCIC_SETW (TCIC_DATA, base);
  560.     
  561.     ioctl  = TCIC_ICTL_QUIET | (sock << TCIC_ICTL_SS_SHFT);
  562.     ioctl |= (len == 0) ? TCIC_ICTL_TINY : 0;
  563.     ioctl |= (io->flags & MAP_ACTIVE) ? TCIC_ICTL_ENA : 0;
  564.     ioctl |= io->extraws & TCIC_ICTL_WSCNT_MASK;
  565.     ioctl |= (io->flags & MAP_16BIT) ? TCIC_ICTL_BW_16 : TCIC_ICTL_BW_8;
  566.     TCIC_SETW (TCIC_ADDR, addr + TCIC_ICTL_X);
  567.     TCIC_SETW (TCIC_DATA, ioctl);
  568.     
  569.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  570.     return (OK);
  571.     }
  572. /*******************************************************************************
  573. *
  574. * tcicMemwinGet - Get the memory window of the socket.
  575. *
  576. * This routine gets the memory window of the socket.
  577. *
  578. * RETURNS: OK, or ERROR if the window number is greater than max windows.
  579. */
  580. LOCAL STATUS tcicMemwinGet
  581.     (
  582.     int   sock, /* socket no. */
  583.     PCMCIA_MEMWIN *mem /* memory window structure to get */
  584.     )
  585.     {
  586.     long base;
  587.     long mmap;
  588.     short addr;
  589.     short ctl;
  590.     
  591.     if (mem->window >= TCIC_MEM_WINDOWS)
  592. return (ERROR);
  593.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  594.     TCIC_SETW (TCIC_ADDR+2, TCIC_ADR2_INDREG | (sock << TCIC_SS_SHFT));
  595.     addr = TCIC_MWIN(sock, mem->window);
  596.     
  597.     TCIC_SETW (TCIC_ADDR, addr + TCIC_MBASE_X);
  598.     base = TCIC_GETW (TCIC_DATA);
  599.     if (base & TCIC_MBASE_4K_BIT)
  600. {
  601. mem->start = base & TCIC_MBASE_HA_MASK;
  602. mem->stop  = mem->start;
  603.         }
  604.     else
  605. {
  606. base &= TCIC_MBASE_HA_MASK;
  607. mem->start = (base & (base-1));
  608. mem->stop  = mem->start + (base ^ (base-1));
  609.         }
  610.     mem->start = mem->start << TCIC_MBASE_HA_SHFT;
  611.     mem->stop  = (mem->stop << TCIC_MBASE_HA_SHFT) + 0x0fff;
  612.     
  613.     TCIC_SETW (TCIC_ADDR, addr + TCIC_MMAP_X);
  614.     mmap = TCIC_GETW(TCIC_DATA);
  615.     mem->flags = (mmap & TCIC_MMAP_REG) ? MAP_ATTRIB : 0;
  616.     mmap = (base + mmap) & TCIC_MMAP_CA_MASK;
  617.     mem->cardstart = mmap << TCIC_MMAP_CA_SHFT;
  618.     
  619.     TCIC_SETW (TCIC_ADDR, addr + TCIC_MCTL_X);
  620.     ctl = TCIC_GETW (TCIC_DATA);
  621.     mem->flags |= (ctl & TCIC_MCTL_ENA) ? MAP_ACTIVE : 0;
  622.     mem->flags |= (ctl & TCIC_MCTL_B8) ? 0 : MAP_16BIT;
  623.     mem->flags |= (ctl & TCIC_MCTL_WP) ? MAP_WRPROT : 0;
  624.     mem->extraws = (ctl & TCIC_MCTL_WSCNT_MASK);
  625.     
  626.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  627.     return (OK);
  628.     }
  629. /*******************************************************************************
  630. *
  631. * tcicMemwinSet - 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 tcicMemwinSet
  638.     (
  639.     int   sock, /* socket no. */
  640.     PCMCIA_MEMWIN *mem /* memory window structure to set */
  641.     )
  642.     {
  643.     short addr;
  644.     short ctl;
  645.     long base;
  646.     long len;
  647.     long mmap;
  648.     
  649.     if ((mem->window >= TCIC_MEM_WINDOWS) || (mem->cardstart > 0xffffff) ||
  650. (mem->start > 0xffffff) || (mem->stop > 0xffffff) ||
  651. (mem->start > mem->stop) || (mem->extraws > 7))
  652. return (ERROR);
  653.     semTake (&tcicMuteSem, WAIT_FOREVER); /* mutual execlusion start */
  654.     TCIC_SETW (TCIC_ADDR+2, TCIC_ADR2_INDREG | (sock << TCIC_SS_SHFT));
  655.     addr = TCIC_MWIN(sock, mem->window);
  656.     base = mem->start & ~0xfff;
  657.     len  = (mem->stop - base) | 0xfff;
  658.     if (len == 0x0fff)
  659. base = (base >> TCIC_MBASE_HA_SHFT) | TCIC_MBASE_4K_BIT;
  660.     else
  661. base = (base | (len+1)>>1) >> TCIC_MBASE_HA_SHFT;
  662.     TCIC_SETW (TCIC_ADDR, addr + TCIC_MBASE_X);
  663.     TCIC_SETW (TCIC_DATA, base);
  664.     
  665.     mmap = (mem->cardstart >> TCIC_MMAP_CA_SHFT) - base;
  666.     mmap &= TCIC_MMAP_CA_MASK;
  667.     if (mem->flags & MAP_ATTRIB)
  668. mmap |= TCIC_MMAP_REG;
  669.     TCIC_SETW (TCIC_ADDR, addr + TCIC_MMAP_X);
  670.     TCIC_SETW (TCIC_DATA, mmap);
  671.     ctl  = TCIC_MCTL_QUIET | (sock << TCIC_MCTL_SS_SHFT);
  672.     ctl |= mem->extraws & TCIC_MCTL_WSCNT_MASK;
  673.     ctl |= (mem->flags & MAP_16BIT) ? 0 : TCIC_MCTL_B8;
  674.     ctl |= (mem->flags & MAP_WRPROT) ? TCIC_MCTL_WP : 0;
  675.     ctl |= (mem->flags & MAP_ACTIVE) ? TCIC_MCTL_ENA : 0;
  676.     TCIC_SETW (TCIC_ADDR, addr + TCIC_MCTL_X);
  677.     TCIC_SETW (TCIC_DATA, ctl);
  678.     
  679.     semGive (&tcicMuteSem);   /* mutual execlusion stop */
  680.     return (OK);
  681.     }
  682. /*******************************************************************************
  683. *
  684. * tcicSetl - Set a long word value to the register.
  685. *
  686. * This routine sets a long word value to the register.
  687. *
  688. * RETURNS: N/A
  689. */
  690. LOCAL void tcicSetl
  691.     (
  692.     int  reg, /* register no. */
  693.     long value /* value to set */
  694.     )
  695.     {
  696.     sysOutWord (tcicBase+reg,   value & 0xffff);
  697.     sysOutWord (tcicBase+reg+2, value >> 16);
  698.     }
  699. /*******************************************************************************
  700. *
  701. * tcicGetl - Get a long word value from the register.
  702. *
  703. * This routine gets a long word value from the register.
  704. *
  705. * RETURNS: A long word value of the register.
  706. */
  707. LOCAL long tcicGetl
  708.     (
  709.     int  reg /* register no. */
  710.     )
  711.     {
  712.     long value0;
  713.     long value1;
  714.     value0 = sysInWord (tcicBase+reg);
  715.     value1 = sysInWord (tcicBase+reg+2);
  716.     return ((value1 << 16) | (value0 & 0xffff));
  717.     }
  718. /*******************************************************************************
  719. *
  720. * tcicAuxGetb - Get a byte value from the aux register.
  721. *
  722. * This routine gets a byte value from the aux register.
  723. *
  724. * RETURNS: A byte value of the register.
  725. */
  726. LOCAL char tcicAuxGetb
  727.     (
  728.     int reg /* register no. */
  729.     )
  730.     {
  731.     char mode = (TCIC_GETB (TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
  732.     TCIC_SETB (TCIC_MODE, mode);
  733.     return (TCIC_GETB (TCIC_AUX));
  734.     }
  735. /*******************************************************************************
  736. *
  737. * tcicAuxSetb - Set a byte value to the aux register.
  738. *
  739. * This routine sets a byte value to the aux register.
  740. *
  741. * RETURNS: N/A
  742. */
  743. LOCAL void tcicAuxSetb
  744.     (
  745.     int  reg, /* register no. */
  746.     char value /* value to set */
  747.     )
  748.     {
  749.     char mode = (TCIC_GETB (TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
  750.     TCIC_SETB (TCIC_MODE, mode);
  751.     TCIC_SETB (TCIC_AUX, value);
  752.     }
  753. #ifdef __unused__
  754. /*******************************************************************************
  755. *
  756. * tcicAuxGetw - Get a word value from the aux register.
  757. *
  758. * This routine gets a word value from the aux register.
  759. *
  760. * RETURNS: A word value of the register.
  761. */
  762. LOCAL short tcicAuxGetw
  763.     (
  764.     int reg /* register no. */
  765.     )
  766.     {
  767.     char mode = (TCIC_GETB (TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
  768.     TCIC_SETB (TCIC_MODE, mode);
  769.     return (TCIC_GETW (TCIC_AUX));
  770.     }
  771. #endif
  772. /*******************************************************************************
  773. *
  774. * tcicAuxSetw - Set a word value to the aux register.
  775. *
  776. * This routine sets a word value to the aux register.
  777. *
  778. * RETURNS: N/A
  779. */
  780. LOCAL void tcicAuxSetw
  781.     (
  782.     int   reg, /* register no. */
  783.     short value /* value to set */
  784.     )
  785.     {
  786.     char mode = (TCIC_GETB (TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
  787.     TCIC_SETB (TCIC_MODE, mode);
  788.     TCIC_SETW (TCIC_AUX, value);
  789.     }