Subversion Repositories f9daq

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
19 f9daq 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
}