Subversion Repositories f9daq

Rev

Rev 19 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. //-------------------------------------------------------------------------
  2. // WINNT driver for PCIVME interface from ARW Elektronik, Germany ---------
  3. // all around recognition and basic services of VMEMM
  4. //
  5. // (c) 1999-2004 ARW Elektronik
  6. //
  7. // this source code is published under GPL (Open Source). You can use, redistrubute and
  8. // modify it unless this header   is not modified or deleted. No warranty is given that
  9. // this software will work like expected.
  10. // This product is not authorized for use as critical component in life support systems
  11. // wihout the express written approval of ARW Elektronik Germany.
  12. //
  13. // Please announce changes and hints to ARW Elektronik
  14. //
  15. // $Log: pcivme_v.c,v $
  16. // Revision 1.3  2004/07/24 07:07:26  klaus
  17. // Update copyright to 2004
  18. //
  19. // Revision 1.2  2003/11/15 19:12:51  klaus
  20. // Update copyright to 2003
  21. //
  22. // Revision 1.1.1.1  2003/11/14 23:16:33  klaus
  23. // First put into repository
  24. //
  25. // Revision 1.3  2002/10/27 16:17:48  klaus
  26. // Typing bug fixed caused at log addition
  27. //
  28. // Revision 1.2  2002/10/27 16:11:02  klaus
  29. // Added CVS log into header
  30. //
  31. // what                                            who          when
  32. // started                                         AR           02.07.1999
  33. // first release 1.0                                                       AR                   17.10.1999
  34. // changed resource allocation caused by WIN2000   AR           08.06.2002
  35. //
  36.  
  37. //-------------------------------------------------------------------------
  38. // INCLUDES
  39. //
  40. #include <ntddk.h>
  41. #include <pcivme_drv.h>
  42. #include <pcivme_v.h>
  43. #include <pciif.h>                      // all around the pci interface
  44.  
  45. #ifndef WORD                            // don't touch include files of WIN95 driver
  46. #define WORD USHORT
  47. #endif
  48.  
  49. #ifndef DWORD
  50. #define DWORD ULONG
  51. #endif
  52.  
  53. //------------------------------------------------------------------------
  54. // PROTOTYPES
  55. //
  56.  
  57. //------------------------------------------------------------------------
  58. // GLOBALS
  59. //
  60.  
  61. //------------------------------------------------------------------------
  62. // FUNCTIONS
  63. //
  64.  
  65. //------------------------------------------------------------------------
  66. // test connection to VMEMM devices without disturbing anything
  67. //
  68. NTSTATUS TestConnection(PCIADA *pciada)
  69. {
  70.         USHORT *pwADRH = (USHORT *)((ULONG)(pciada->pvVirtIfr) + (ULONG)ADRH);
  71.         USHORT *pwADRL = (USHORT *)((ULONG)(pciada->pvVirtIfr) + (ULONG)ADRL);
  72.         int i;
  73.         USHORT wRet;
  74.     USHORT wADRHContent;
  75.     USHORT wADRLContent;
  76.  
  77.        
  78.         KdPrint(("TestConnection()\n"));
  79.        
  80.         wADRHContent = READ_REGISTER_USHORT(pwADRH);    // save previous content
  81.         wADRLContent = READ_REGISTER_USHORT(pwADRL);
  82.  
  83.         for (i = 0; i < 10000; i++)
  84.         {
  85.                 WRITE_REGISTER_USHORT(pwADRH, 0x5555);
  86.                 WRITE_REGISTER_USHORT(pwADRL, 0xAAAA);
  87.                 wRet = READ_REGISTER_USHORT(pwADRH);
  88.                 if (wRet != 0x5555) return STATUS_UNSUCCESSFUL;
  89.    
  90.                 WRITE_REGISTER_USHORT(pwADRH, 0xAAAA);
  91.                 WRITE_REGISTER_USHORT(pwADRL, 0x5555);
  92.                 wRet = READ_REGISTER_USHORT(pwADRH);
  93.                 if (wRet != 0xAAAA) return STATUS_UNSUCCESSFUL;
  94.  
  95.                 WRITE_REGISTER_USHORT(pwADRH, 0x0000);
  96.                 WRITE_REGISTER_USHORT(pwADRL, 0xFFFF);
  97.                 wRet = READ_REGISTER_USHORT(pwADRH);
  98.                 if (wRet != 0x0000) return STATUS_UNSUCCESSFUL;
  99.  
  100.                 WRITE_REGISTER_USHORT(pwADRH, 0xFFFF);
  101.                 WRITE_REGISTER_USHORT(pwADRL, 0x0000);
  102.                 wRet = READ_REGISTER_USHORT(pwADRH);
  103.                 if (wRet != 0xFFFF) return STATUS_UNSUCCESSFUL;
  104.         }
  105.  
  106.         WRITE_REGISTER_USHORT(pwADRH, wADRHContent);    // restore previous content
  107.         WRITE_REGISTER_USHORT(pwADRL, wADRLContent);
  108.  
  109.         KdPrint(("TestConnection() OK.\n"));
  110.  
  111.         return STATUS_SUCCESS;
  112. }
  113.  
  114. //------------------------------------------------------------------------
  115. // scan VMEMM devices without disturbing anything
  116. //
  117. NTSTATUS PCIVMEScanVMEMM(PDEVICE_OBJECT deviceObj)
  118. {
  119.         int i;
  120.         int nPCIADAs = ((DEVICE_EXT*)(deviceObj->DeviceExtension))->nPCIADAs;
  121.         PCIADA           *pciada;
  122.         USHORT           wCntrl;
  123.         USHORT                   wIntCSR;
  124.         USHORT                   wVMEMMStatus;
  125.  
  126.         KdPrint(("PCIVMEScanVMEMM()\n"));
  127.  
  128.     for (i = 0; i < nPCIADAs; i++)
  129.     {
  130.                 pciada = &((DEVICE_EXT*)(deviceObj->DeviceExtension))->pciada[i];
  131.                
  132.                 wCntrl  = READ_REGISTER_USHORT(pciada->pwCntrl);   // save it for later use
  133.         wIntCSR = READ_REGISTER_USHORT(pciada->pwIntCSR);
  134.  
  135.                 WRITE_REGISTER_USHORT(pciada->pwIntCSR, DISABLE_PCIADA_IRQS);
  136.                 WRITE_REGISTER_USHORT(pciada->pwCntrl, RELEASE_VMEMM);  // open it for test
  137.  
  138.                 if (wCntrl & 0x0800)
  139.                 {
  140.                         if (TestConnection(pciada) == STATUS_SUCCESS)
  141.                         {      
  142.                                 wVMEMMStatus  = READ_REGISTER_USHORT(pciada->pvVirtIfr);
  143.  
  144.                                 pciada->bConnected              = TRUE;
  145.  
  146.                                 // interpret the content
  147.                                 pciada->bWordMode               = (wVMEMMStatus & FLAG_WORD)   ? TRUE : FALSE;
  148.                                 pciada->bSysControl             = (wVMEMMStatus & FLAG_SYSCTL) ? TRUE : FALSE;
  149.                                 pciada->wModuleNumber   = (wVMEMMStatus & MASK_MODNR)   >> 4;
  150.                                 pciada->wFPGAVersion    = (wVMEMMStatus & MASK_FPGA)    >> 8;
  151.                                 pciada->wModuleType             = (wVMEMMStatus & MASK_MODTYPE) >> 12;
  152.  
  153.                                 // calculate some heavy used addresses
  154.                                 pciada->pwCSR                   = (PUSHORT)((ULONG)(pciada->pvVirtIfr) + CSR);
  155.                                 pciada->pbModifier              = (PUCHAR) ((ULONG)(pciada->pvVirtIfr) + VICBASE + AMSR);
  156.                                 pciada->pdwVMEAdr               = (PULONG) ((ULONG)(pciada->pvVirtIfr) + ADRHL);
  157.                                 pciada->pwIRQStat               = (PUSHORT)((ULONG)(pciada->pvVirtIfr) + VICRES);
  158.                                 pciada->pbVector                = (PUCHAR) ((ULONG)(pciada->pvVirtIfr) + VECBASE);
  159.                                 pciada->pvVME                   = (PVOID)  ((ULONG)(pciada->pvVirtIfr) + VMEBASE);
  160.  
  161.                                 KdPrint(("PCIADA %d <-> VMEMM %d\n", i, pciada->wModuleNumber));
  162.                         }
  163.                         else  
  164.                                 pciada->wModuleNumber = 0xFFFF;  // not recognized, take it out
  165.                 }
  166.                 else
  167.                         pciada->wModuleNumber = 0xFFFF;  // not recognized, take it out
  168.  
  169.                 if (pciada->wModuleNumber != 0xFFFF)
  170.                   WRITE_REGISTER_USHORT(pciada->pwCntrl,  wCntrl);   // restore state
  171.                 else
  172.                   WRITE_REGISTER_USHORT(pciada->pwCntrl,  INHIBIT_VMEMM);  
  173.  
  174.                 WRITE_REGISTER_USHORT(pciada->pwIntCSR, wIntCSR);    // restore interrupt masks
  175.     }
  176.  
  177.         return STATUS_SUCCESS;
  178. }
  179.  
  180.  
  181. //------------------------------------------------------------------------
  182. // deinit all PCIADAs in a passive state
  183. //
  184. NTSTATUS PCIVMEDeInitPCIADAs(PDEVICE_OBJECT deviceObj)
  185. {
  186.         int              i;
  187.         DEVICE_EXT       *pDevExt = (DEVICE_EXT*)deviceObj->DeviceExtension;
  188.         int                              nPCIADAs = pDevExt->nPCIADAs;
  189.         PCIADA           *pciada;
  190.  
  191.         KdPrint(("PCIVMEDeInitPCIADAs()\n"));
  192.  
  193.         // dis connect the interrupts to service routines
  194.         for (i = 0; i < nPCIADAs; i++)
  195.         {
  196.                 pciada = &pDevExt->pciada[i];
  197.  
  198.                 WRITE_REGISTER_USHORT(pciada->pwIntCSR, DISABLE_PCIADA_IRQS);
  199.                 WRITE_REGISTER_USHORT(pciada->pwCntrl,  INHIBIT_VMEMM);
  200.         }
  201.  
  202.         return STATUS_SUCCESS;
  203. }
  204.