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

VxWorks

开发平台:

C/C++

  1. /* sramDrv.c - PCMCIA SRAM device driver */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01e,21jun00,rsh  upgrade to dosFs 2.0
  8. 01d,16jan97,hdn  added pCtrl->memBase.
  9. 01c,28mar96,jdi  doc: cleaned up language and format.
  10. 01b,22feb96,hdn  cleaned up
  11. 01a,28feb95,hdn  written based on memDrv.c and ramDrv.c.
  12. */
  13. /*
  14. DESCRIPTION
  15. This is a device driver for the SRAM PC card.  The memory location and size
  16. are specified when the "disk" is created.
  17. USER-CALLABLE ROUTINES
  18. Most of the routines in this driver are accessible only through the I/O
  19. system.  However, two routines must be called directly:  sramDrv() to
  20. initialize the driver, and sramDevCreate() to create block devices.
  21. Additionally, the sramMap() routine is called directly to map the PCMCIA
  22. memory onto the ISA address space.  Note that this routine does not use
  23. any mutual exclusion or synchronization mechanism; thus, special care must
  24. be taken in the multitasking environment.
  25. Before using this driver, it must be initialized by calling sramDrv().  This
  26. routine should be called only once, before any reads, writes, or calls to
  27. sramDevCreate() or sramMap().  It can be called from usrRoot() in usrConfig.c
  28. or at some later point.
  29. SEE ALSO:
  30. .pG "I/O System"
  31. LINTLIBRARY
  32. */
  33. #include "vxWorks.h"
  34. #include "ioLib.h"
  35. #include "memLib.h"
  36. #include "errnoLib.h"
  37. #include "string.h"
  38. #include "stdlib.h"
  39. #include "stdio.h"
  40. #include "sysLib.h"
  41. #include "logLib.h"
  42. #include "private/semLibP.h"
  43. #include "drv/pcmcia/pcmciaLib.h"
  44. #include "drv/pcmcia/sramDrv.h"
  45. /* defines */
  46. #define SRAM_WINDOW 1
  47. /* imports */
  48. IMPORT PCMCIA_CTRL pcmciaCtrl;
  49. IMPORT SRAM_RESOURCE sramResources[];
  50. /* globals */
  51. SRAM_CTRL sramCtrl;
  52. int sramResourceNumEnt;
  53. /* locals */
  54. LOCAL BOOL sramDrvInstalled = FALSE;
  55. LOCAL PCMCIA_MEMWIN sramMemwin = {1,0,0,0,0,0};
  56. /* forward declarations */
  57. LOCAL STATUS sramRead (SRAM_DEV *pSramDev, int startBlk, int numBlks, 
  58.    char *pChar);
  59. LOCAL STATUS sramWrite (SRAM_DEV *pSramDev, int startBlk, int numBlks,
  60.    char *pChar);
  61. LOCAL STATUS sramIoctl (SRAM_DEV *pSramDev, int function, int arg);
  62. LOCAL STATUS sramStatusChk  (SRAM_DEV *pSramDev);
  63. /*******************************************************************************
  64. *
  65. * sramDrv - install a PCMCIA SRAM memory driver
  66. *
  67. * This routine initializes a PCMCIA SRAM memory driver.  It must be called once,
  68. * before any other routines in the driver.
  69. *
  70. * RETURNS:
  71. * OK, or ERROR if the I/O system cannot install the driver.
  72. */
  73. STATUS sramDrv
  74.     (
  75.     int sock /* socket no. */
  76.     )
  77.     {
  78.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  79.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  80.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  81.     SEM_ID muteSemID = &sramCtrl.muteSem[sock];
  82.     SEM_ID syncSemID = &sramCtrl.syncSem[sock];
  83.     int ix;
  84.     if ((!pChip->installed) || (!pCard->detected))
  85. return (ERROR);
  86.     if (!sramDrvInstalled)
  87. {
  88. for (ix = 0; ix < MAX_SOCKETS; ix++)
  89.     {
  90.             semBInit (&sramCtrl.syncSem[ix], SEM_Q_FIFO, SEM_EMPTY);
  91.             semMInit (&sramCtrl.muteSem[ix], SEM_Q_PRIORITY |
  92.       SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
  93.     }
  94.         sramDrvInstalled = TRUE;
  95. }
  96.     if (!pCard->installed)
  97. {
  98.         semBInit (syncSemID, SEM_Q_FIFO, SEM_EMPTY);
  99.         semMInit (muteSemID, SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  100.   SEM_INVERSION_SAFE);
  101. }
  102.     return (OK);
  103.     }
  104. /*******************************************************************************
  105. *
  106. * sramMap - map PCMCIA memory onto a specified ISA address space
  107. *
  108. * This routine maps PCMCIA memory onto a specified ISA address space.
  109. *
  110. * RETURNS:
  111. * OK, or ERROR if the memory cannot be mapped.
  112. */
  113. STATUS sramMap
  114.     (
  115.     int sock, /* socket no. */
  116.     int type, /* 0: common  1: attribute */
  117.     int start, /* ISA start address */
  118.     int stop, /* ISA stop address */
  119.     int offset, /* card offset address */
  120.     int extraws /* extra wait state */
  121.     )
  122.     {
  123.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  124.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  125.     PCMCIA_MEMWIN memwin;
  126.     if ((!pChip->installed) || (sock >= pChip->socks))
  127. return (ERROR);
  128.     memwin.window = SRAM_WINDOW;
  129.     memwin.flags = MAP_ACTIVE | MAP_16BIT;
  130.     if (type == 1)
  131.         memwin.flags = MAP_ACTIVE | MAP_16BIT | MAP_ATTRIB;
  132.     memwin.extraws = extraws;
  133.     memwin.start = start;
  134.     memwin.stop = stop;
  135.     memwin.cardstart = offset & 0xfffff000;
  136.     if ((* pChip->memwinSet)(sock, &memwin) != OK)
  137.         return (ERROR);
  138.     return (OK);
  139.     }
  140. /*******************************************************************************
  141. *
  142. * sramDevCreate - create a PCMCIA memory disk device
  143. *
  144. * This routine creates a PCMCIA memory disk device.
  145. *
  146. * RETURNS:
  147. * A pointer to a block device structure (BLK_DEV), or NULL if memory cannot
  148. * be allocated for the device structure.
  149. *
  150. * SEE ALSO: ramDevCreate()
  151. */
  152. BLK_DEV *sramDevCreate
  153.     (
  154.     int sock, /* socket no. */
  155.     int bytesPerBlk, /* number of bytes per block */
  156.     int blksPerTrack, /* number of blocks per track */
  157.     int nBlocks, /* number of blocks on this device */
  158.     int blkOffset /* no. of blks to skip at start of device */
  159.     )
  160.  
  161.     {
  162.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  163.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  164.     PCMCIA_CARD *pCard = &pCtrl->card[sock];
  165.     SRAM_RESOURCE *pSram = &sramResources[sock];
  166.     PCCARD_RESOURCE *pResource = &pSram->resource;
  167.     SRAM_DEV *pSramDev; /* ptr to created SRAM_DEV struct */
  168.     BLK_DEV *pBlkDev; /* ptr to BLK_DEV struct in SRAM_DEV */
  169.     if ((!pChip->installed) || (!pCard->installed) ||
  170. (sock >= sramResourceNumEnt))
  171.         return (NULL);
  172.     /* Set up defaults for any values not specified */
  173.     if (bytesPerBlk == 0)
  174. bytesPerBlk = DEFAULT_SEC_SIZE;
  175.     if (nBlocks == 0)
  176. nBlocks = DEFAULT_DISK_SIZE / bytesPerBlk;
  177.     if (blksPerTrack == 0)
  178. blksPerTrack = nBlocks;
  179.     if ((bytesPerBlk * nBlocks) >= pResource->memLength)
  180.         return (NULL);
  181.     /* Allocate a SRAM_DEV structure for device */
  182.     pSramDev = (SRAM_DEV *) malloc (sizeof (SRAM_DEV));
  183.     if (pSramDev == NULL)
  184. return (NULL); /* no memory */
  185.     /* Initialize BLK_DEV structure (in SRAM_DEV) */
  186.     pBlkDev = &pSramDev->blkDev;
  187.     pBlkDev->bd_nBlocks      = nBlocks; /* number of blocks */
  188.     pBlkDev->bd_bytesPerBlk  = bytesPerBlk; /* bytes per block */
  189.     pBlkDev->bd_blksPerTrack = blksPerTrack; /* blocks per track */
  190.     pBlkDev->bd_nHeads       = 1; /* one "head" */
  191.     pBlkDev->bd_removable    = TRUE; /* removable */
  192.     pBlkDev->bd_retry      = 1; /* retry count */
  193.     pBlkDev->bd_readyChanged = TRUE; /* new ready status */
  194.     pBlkDev->bd_mode      = O_RDWR; /* initial mode for device */
  195.     pBlkDev->bd_blkRd      = sramRead; /* read block function */
  196.     pBlkDev->bd_blkWrt      = sramWrite; /* write block function */
  197.     pBlkDev->bd_ioctl      = sramIoctl; /* ioctl function */
  198.     pBlkDev->bd_reset      = NULL; /* no reset function */
  199.     pBlkDev->bd_statusChk    = sramStatusChk; /* check-status function */
  200.     pBlkDev->bd_statusChk    = NULL; /* check-status function */
  201.     /* Initialize remainder of device struct */
  202.     pSramDev->blkOffset = blkOffset; /* block offset */
  203.     pSramDev->sock = sock; /* socket no. */
  204.     return (&pSramDev->blkDev);
  205.     }
  206. /*******************************************************************************
  207. *
  208. * sramRead - read one or more blocks from a PCMCIA memory disk volume
  209. *
  210. * This routine reads one or more blocks from the specified volume,
  211. * starting with the specified block number.  The byte offset is
  212. * calculated and the PCMCIA memory disk data is copied to the specified buffer.
  213. *
  214. * If any block offset was specified during sramDevCreate(), it is added
  215. * to <startBlk> before the transfer takes place.
  216. *
  217. * RETURNS: OK, or ERROR if mapping or read fails.
  218. */
  219. LOCAL STATUS sramRead
  220.     (
  221.     SRAM_DEV *pSramDev, /* pointer to device desriptor */
  222.     int      startBlk, /* starting block number to read */
  223.     int      numBlks, /* number of blocks to read */
  224.     char     *pChar /* pointer to buffer to receive data */
  225.     )
  226.     {
  227.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  228.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  229.     PCMCIA_CARD *pCard = &pCtrl->card[pSramDev->sock];
  230.     SRAM_RESOURCE *pSram = &sramResources[pSramDev->sock];
  231.     PCCARD_RESOURCE *pResource = &pSram->resource;
  232.     SEM_ID muteSemID = &sramCtrl.muteSem[pSramDev->sock];
  233.     SEM_ID syncSemID = &sramCtrl.syncSem[pSramDev->sock];
  234.     u_int bytesPerBlk = pSramDev->blkDev.bd_bytesPerBlk;
  235.     u_int windowSize = pResource->memStop - pResource->memStart + 1;
  236.     u_int nbytes = bytesPerBlk * numBlks;
  237.     u_int offset = (u_int)pResource->memOffset + 
  238.   ((startBlk + pSramDev->blkOffset) * 
  239.   bytesPerBlk);
  240.     u_int copiedBytes = 0;
  241.     u_int length;
  242.     PCMCIA_MEMWIN memwin;
  243.     /* sanity check */
  244.     if ((!pCard->installed) ||
  245.         ((block_t)(startBlk + numBlks) > pSramDev->blkDev.bd_nBlocks) ||
  246. (offset >= (u_int)pResource->memLength))
  247. return (ERROR);
  248. #ifdef SRAM_DEBUG
  249.     printf ("sramRead: startBlk=%d numBlks=%d p=0x%xn",
  250.     startBlk, numBlks, pChar);
  251. #endif
  252.     if (pCard->cardStatus & PC_BATDEAD)
  253. {
  254. (void) errnoSet (S_pcmciaLib_BATTERY_DEAD);
  255. return (ERROR);
  256. }
  257.     if (pCard->cardStatus & PC_BATWARN)
  258. {
  259. (void) errnoSet (S_pcmciaLib_BATTERY_WARNING);
  260. return (ERROR);
  261. }
  262.     if (pCard->cardStatus & PC_WRPROT)
  263.         pSramDev->blkDev.bd_mode = O_RDONLY;
  264.     /* Read the block(s) */
  265.     if (semTake (muteSemID, WAIT_FOREVER) == ERROR)
  266. return (ERROR);
  267.     while (copiedBytes < nbytes)
  268. {
  269. memwin.window = SRAM_WINDOW;
  270. memwin.flags = MAP_ACTIVE | MAP_16BIT;
  271. memwin.extraws = pResource->memExtraws;
  272. memwin.start = pResource->memStart;
  273. memwin.stop = pResource->memStop;
  274. memwin.cardstart= offset & 0xfffff000;
  275. if ((* pChip->memwinSet)(pSramDev->sock, &memwin) != OK)
  276.     {
  277.     semGive (muteSemID);
  278.     return (ERROR);
  279.     }
  280. if (((* pChip->status)(pSramDev->sock) & PC_READY) == 0)
  281.     if (semTake(syncSemID, sysClkRateGet()) != OK)
  282. {
  283. semGive (muteSemID);
  284. return (ERROR);
  285. }
  286. length = min (nbytes - copiedBytes, (windowSize - (offset & 0xfff)));
  287. bcopy ((char *)memwin.start + (offset & 0xfff) + pCtrl->memBase,
  288.        pChar, length);
  289. offset += length;
  290. copiedBytes  += length;
  291. pChar  += length;
  292. }
  293.     if ((* pChip->memwinSet)(pSramDev->sock, &sramMemwin) != OK)
  294. {
  295. semGive (muteSemID);
  296. return (ERROR);
  297. }
  298.     semGive (muteSemID);
  299.     return (OK);
  300.     }
  301. /*******************************************************************************
  302. *
  303. * sramWrite - write one or more blocks to a PCMCIA memory disk volume
  304. *
  305. * This routine writes one or more blocks to the specified volume,
  306. * starting with the specified block number.  The byte offset is
  307. * calculated and the buffer data is copied to the PCMCIA memory disk.
  308. *
  309. * If any block offset was specified during sramDevCreate(), it is added
  310. * to <startBlk> before the transfer takes place.
  311. *
  312. * RETURNS: OK, or ERROR if mapping or write fails.
  313. */
  314. LOCAL STATUS sramWrite
  315.     (
  316.     SRAM_DEV *pSramDev, /* pointer to device desriptor */
  317.     int      startBlk, /* starting block number to write */
  318.     int      numBlks, /* number of blocks to write */
  319.     char     *pChar  /* pointer to buffer of data to write */
  320.     )
  321.     {
  322.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  323.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  324.     PCMCIA_CARD *pCard = &pCtrl->card[pSramDev->sock];
  325.     SRAM_RESOURCE *pSram = &sramResources[pSramDev->sock];
  326.     PCCARD_RESOURCE *pResource = &pSram->resource;
  327.     SEM_ID muteSemID = &sramCtrl.muteSem[pSramDev->sock];
  328.     SEM_ID syncSemID = &sramCtrl.syncSem[pSramDev->sock];
  329.     u_int bytesPerBlk = pSramDev->blkDev.bd_bytesPerBlk;
  330.     u_int windowSize = pResource->memStop - pResource->memStart + 1;
  331.     u_int nbytes = bytesPerBlk * numBlks;
  332.     u_int offset = (u_int)pResource->memOffset + 
  333.   ((startBlk + pSramDev->blkOffset) *
  334.   bytesPerBlk);
  335.     u_int copiedBytes = 0;
  336.     u_int length;
  337.     PCMCIA_MEMWIN memwin;
  338.     /* sanity check */
  339.     if ((!pCard->installed) ||
  340.         ((block_t)(startBlk + numBlks) > pSramDev->blkDev.bd_nBlocks) ||
  341. (offset >= (u_int)pResource->memLength))
  342. return (ERROR);
  343. #ifdef SRAM_DEBUG
  344.     printf ("sramWrite: startBlk=%d numBlks=%d p=0x%xn",
  345.     startBlk, numBlks, pChar);
  346. #endif
  347.     if (pCard->cardStatus & PC_BATDEAD)
  348. {
  349. (void) errnoSet (S_pcmciaLib_BATTERY_DEAD);
  350. return (ERROR);
  351. }
  352.     if (pCard->cardStatus & PC_BATWARN)
  353. {
  354. (void) errnoSet (S_pcmciaLib_BATTERY_WARNING);
  355. return (ERROR);
  356. }
  357.     if (pCard->cardStatus & PC_WRPROT)
  358. {
  359. (void) errnoSet (S_ioLib_WRITE_PROTECTED);
  360.         pSramDev->blkDev.bd_mode = O_RDONLY;
  361. return (ERROR);
  362. }
  363.     /* Write the block(s) */
  364.     if (semTake (muteSemID, WAIT_FOREVER) == ERROR)
  365. return (ERROR);
  366.     while (copiedBytes < nbytes)
  367. {
  368. memwin.window = SRAM_WINDOW;
  369. memwin.flags = MAP_ACTIVE | MAP_16BIT;
  370. memwin.extraws = pResource->memExtraws;
  371. memwin.start = pResource->memStart;
  372. memwin.stop = pResource->memStop;
  373. memwin.cardstart= offset & 0xfffff000;
  374. if ((* pChip->memwinSet)(pSramDev->sock, &memwin) != OK)
  375.     {
  376.     semGive (muteSemID);
  377.     return (ERROR);
  378.     }
  379. if (((* pChip->status)(pSramDev->sock) & PC_READY) == 0)
  380.     if (semTake(syncSemID, sysClkRateGet()) != OK)
  381. {
  382. semGive (muteSemID);
  383. return (ERROR);
  384. }
  385. length = min (nbytes - copiedBytes, (windowSize - (offset & 0xfff)));
  386. bcopy (pChar, (char *)memwin.start + (offset & 0xfff) + pCtrl->memBase,
  387.        length);
  388. offset += length;
  389. copiedBytes  += length;
  390. pChar  += length;
  391. }
  392.     if ((* pChip->memwinSet)(pSramDev->sock, &sramMemwin) != OK)
  393. {
  394. semGive (muteSemID);
  395. return (ERROR);
  396. }
  397.     semGive (muteSemID);
  398.     return (OK);
  399.     }
  400. /*******************************************************************************
  401. *
  402. * sramIoctl - do device specific control function
  403. *
  404. * This routine is called when the file system cannot handle an ioctl()
  405. * function.
  406. *
  407. * The FIODISKFORMAT function always returns OK, since a PCMCIA memory disk does
  408. * not require formatting.  All other requests return ERROR.
  409. *
  410. * RETURNS:  OK, or ERROR if there is an error.
  411. *
  412. * ARGSUSED1
  413. */
  414. LOCAL STATUS sramIoctl
  415.     (
  416.     SRAM_DEV *pSramDev, /* device structure pointer */
  417.     int      function, /* function code */
  418.     int      arg  /* some argument */
  419.     )
  420.     {
  421.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  422.     PCMCIA_CARD *pCard = &pCtrl->card[pSramDev->sock];
  423.     int status; /* returned status value */
  424.     if (!pCard->installed)
  425. return (ERROR);
  426. #ifdef SRAM_DEBUG
  427.     printf ("sramIoctl: function=0x%x arg=0x%xn", function, arg);
  428. #endif
  429.     switch (function)
  430. {
  431. case FIODISKFORMAT:
  432.     status = OK;
  433.     break;
  434. default:
  435.     errnoSet (S_ioLib_UNKNOWN_REQUEST);
  436.     status = ERROR;
  437. }
  438.     return (status);
  439.     }
  440. /*******************************************************************************
  441. *
  442. * sramStatusChk - check the status
  443. *
  444. * This routine is called by the file system to check the status.
  445. *
  446. * RETURNS:  OK, or ERROR if there is an error.
  447. *
  448. */
  449. LOCAL STATUS sramStatusChk
  450.     (
  451.     SRAM_DEV *pSramDev /* device structure pointer */
  452.     )
  453.     {
  454.     PCMCIA_CTRL *pCtrl = &pcmciaCtrl;
  455.     PCMCIA_CHIP *pChip = &pCtrl->chip;
  456.     PCMCIA_CARD *pCard = &pCtrl->card[pSramDev->sock];
  457.     SEM_ID muteSemID = &sramCtrl.muteSem[pSramDev->sock];
  458.     BLK_DEV *pBlkDev = &pSramDev->blkDev;
  459.     if (!pCard->installed)
  460. return (ERROR);
  461. #ifdef SRAM_DEBUG
  462.     printf ("sramStatusChk: n");
  463. #endif
  464.     if (pCard->changed)
  465. {
  466. pBlkDev->bd_readyChanged = TRUE;
  467. pCard->changed  = FALSE;
  468. }
  469.     if (semTake (muteSemID, WAIT_FOREVER) == ERROR)
  470. return (ERROR);
  471.     pCard->cardStatus = (* pChip->status) (pSramDev->sock);
  472.     semGive (muteSemID);
  473.     if (pCard->cardStatus & PC_BATDEAD)
  474. {
  475. (void) errnoSet (S_pcmciaLib_BATTERY_DEAD);
  476. return (ERROR);
  477. }
  478.     if (pCard->cardStatus & PC_BATWARN)
  479. {
  480. (void) errnoSet (S_pcmciaLib_BATTERY_WARNING);
  481. return (ERROR);
  482. }
  483.     if (pCard->cardStatus & PC_WRPROT)
  484.         pBlkDev->bd_mode     = O_RDONLY;
  485.     else
  486.         pBlkDev->bd_mode     = O_RDWR;
  487.     return (OK);
  488.     }