Subversion Repositories f9daq

Rev

Rev 11 | Rev 14 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11 Rev 13
1
//-------------------------------------------------------------------------------------------
1
//-------------------------------------------------------------------------------------------
2
// pcivme_ni.c - shared library for ARW pcivme interface (libpcivme.so)
2
// pcivme_ni.c - shared library for ARW pcivme interface (libpcivme.so)
3
//
3
//
4
// Copyright (C) 2002-2004 ARW Elektronik Germany
4
// Copyright (C) 2002-2004 ARW Elektronik Germany
5
//
5
//
6
// this source code is published under LGPL (Open Source). You can use, redistrubute and 
6
// this source code is published under LGPL (Open Source). You can use, redistrubute and 
7
// modify it unless this header  is  not modified or deleted. No warranty is given that 
7
// modify it unless this header  is  not modified or deleted. No warranty is given that 
8
// this software will work like expected.
8
// this software will work like expected.
9
// This product is not authorized for use as critical component in life support systems
9
// This product is not authorized for use as critical component in life support systems
10
// wihout the express written approval of ARW Elektronik Germany.
10
// wihout the express written approval of ARW Elektronik Germany.
11
//
11
//
12
// Please announce changes and hints to ARW Elektronik
12
// Please announce changes and hints to ARW Elektronik
13
// 
13
// 
14
// $Log: pcivme_ni.c,v $
14
// $Log: pcivme_ni.c,v $
15
// Revision 1.8  2004/08/13 19:23:45  klaus
15
// Revision 1.8  2004/08/13 19:23:45  klaus
16
// conversion to kernel-version 2.6, released version 3.0
16
// conversion to kernel-version 2.6, released version 3.0
17
//
17
//
18
// Revision 1.7  2002/10/20 18:07:18  klaus
18
// Revision 1.7  2002/10/20 18:07:18  klaus
19
// changed error handling
19
// changed error handling
20
//
20
//
21
// Revision 1.6  2002/10/18 21:56:28  klaus
21
// Revision 1.6  2002/10/18 21:56:28  klaus
22
// completed functional features, untested
22
// completed functional features, untested
23
//
23
//
24
// Revision 1.5  2002/10/18 21:56:28  klaus
24
// Revision 1.5  2002/10/18 21:56:28  klaus
25
// completed functional features, untested
25
// completed functional features, untested
26
//
26
//
27
// Revision 1.4  2002/10/17 21:16:03  klaus
27
// Revision 1.4  2002/10/17 21:16:03  klaus
28
// filled function bodies
28
// filled function bodies
29
//
29
//
30
// Revision 1.3  2002/10/17 21:16:03  klaus
30
// Revision 1.3  2002/10/17 21:16:03  klaus
31
// filled function bodies
31
// filled function bodies
32
//
32
//
33
// Revision 1.2  2002/10/17 19:05:03  klaus
33
// Revision 1.2  2002/10/17 19:05:03  klaus
34
// VME access is working through test to lib to driver
34
// VME access is working through test to lib to driver
35
//
35
//
36
// Revision 1.1  2002/10/12 22:04:30  klaus
36
// Revision 1.1  2002/10/12 22:04:30  klaus
37
// first work done
37
// first work done
38
//
38
//
39
 
39
 
40
//-------------------------------------------------------------------------------------------
40
//-------------------------------------------------------------------------------------------
41
// INCLUDES
41
// INCLUDES
42
//
42
//
43
#include <stdio.h>
43
#include <stdio.h>
44
#include <stdlib.h>
44
#include <stdlib.h>
45
#include <string.h>
45
#include <string.h>
46
#include <unistd.h>
46
#include <unistd.h>
47
#include <linux/types.h>
47
#include <linux/types.h>
48
#include <sys/ioctl.h>
48
#include <sys/ioctl.h>
49
#include <errno.h>
49
#include <errno.h>
50
#include <ctype.h>
50
#include <ctype.h>
51
#include <sys/types.h>
51
#include <sys/types.h>
52
#include <sys/stat.h>
52
#include <sys/stat.h>
53
#include <fcntl.h>
53
#include <fcntl.h>
54
 
54
 
55
#include <../driver/pcivme.h>
55
#include <../driver/pcivme.h>
56
#include <../driver/vic.h>
56
#include <../driver/vic.h>
57
#include <pcivme_ni.h>
57
#include <pcivme_ni.h>
58
 
58
 
59
//-------------------------------------------------------------------------------------------
59
//-------------------------------------------------------------------------------------------
60
// DEFINES
60
// DEFINES
61
//
61
//
62
#define LOCAL_STRING_LEN 40
62
#define LOCAL_STRING_LEN 40
63
 
63
 
64
//-------------------------------------------------------------------------------------------
64
//-------------------------------------------------------------------------------------------
65
// TYPEDEFS
65
// TYPEDEFS
66
//
66
//
67
 
67
 
68
// storage for path specific data
68
// storage for path specific data
69
typedef struct
69
typedef struct
70
{
70
{
71
    int nFileNo;              // file number to f
71
    int nFileNo;              // file number to f
72
    __u8 cAddressModifier;    // associated VME address modifier
72
    __u8 cAddressModifier;    // associated VME address modifier
73
    __u8 cAccessWidth;        // current access width
73
    __u8 cAccessWidth;        // current access width
74
    int  nLastError;          // != 0 if a previous error occurred
74
    int  nLastError;          // != 0 if a previous error occurred
75
} VMEMM_DEVICE;
75
} VMEMM_DEVICE;
76
 
76
 
77
//-------------------------------------------------------------------------------------------
77
//-------------------------------------------------------------------------------------------
78
// FUNCTIONS
78
// FUNCTIONS
79
//
79
//
80
 
80
 
81
// construct a device file name
81
// construct a device file name
82
static char *szDeviceName(const char *cszBaseName, int nVMEMM)
82
static char *szDeviceName(const char *cszBaseName, int nVMEMM)
83
{
83
{
84
  static char path[LOCAL_STRING_LEN];
84
  static char path[LOCAL_STRING_LEN];
85
  int i = LOCAL_STRING_LEN - 1;
85
  int i = LOCAL_STRING_LEN - 1;
86
 
86
 
87
  path[0] = 0;
87
  path[0] = 0;
88
 
88
 
89
  memset(path, 0, LOCAL_STRING_LEN);
89
  memset(path, 0, LOCAL_STRING_LEN);
90
 
90
 
91
  if (strlen(cszBaseName) >= (LOCAL_STRING_LEN - 3))
91
  if (strlen(cszBaseName) >= (LOCAL_STRING_LEN - 3))
92
      return "";
92
      return "";
93
 
93
 
94
  if (nVMEMM > 15)
94
  if (nVMEMM > 15)
95
      return "";
95
      return "";
96
 
96
 
97
  strncpy(path, cszBaseName, LOCAL_STRING_LEN - 3);
97
  strncpy(path, cszBaseName, LOCAL_STRING_LEN - 3);
98
 
98
 
99
  while ((i--) && (path[i] != '_'));  // search for '_'
99
  while ((i--) && (path[i] != '_'));  // search for '_'
100
 
100
 
101
  if (i)
101
  if (i)
102
  {
102
  {
103
      i++; // go after '_'
103
      i++; // go after '_'
104
      if (nVMEMM >= 10)
104
      if (nVMEMM >= 10)
105
      {
105
      {
106
          path[i] = '1';
106
          path[i] = '1';
107
          nVMEMM -= 10;
107
          nVMEMM -= 10;
108
          i++;
108
          i++;
109
      }
109
      }
110
      path[i] = '0' + nVMEMM;
110
      path[i] = '0' + nVMEMM;
111
      i++;
111
      i++;
112
      path[i] = 0; // trailing 0
112
      path[i] = 0; // trailing 0
113
  }
113
  }
114
  else
114
  else
115
      return "";
115
      return "";
116
 
116
 
117
  return path;
117
  return path;
118
}
118
}
119
 
119
 
120
static int initHardware(VMEMM_DEVICE *dev)
120
static int initHardware(VMEMM_DEVICE *dev)
121
{
121
{
122
    PCIVME_INIT_COMMAND init;
122
    PCIVME_INIT_COMMAND init;
123
 
123
 
124
    init.sVie[0].bDestination = STOP;
124
    init.sVie[0].bDestination = STOP;
125
    init.sVie[0].bAccessType  =
125
    init.sVie[0].bAccessType  =
126
    init.sVie[0].dwValue      =
126
    init.sVie[0].dwValue      =
127
    init.sVie[0].wOffset      = 0;
127
    init.sVie[0].wOffset      = 0;
128
 
128
 
129
    if (ioctl(dev->nFileNo, PCIVME_INIT_HARDWARE, &init) < 0)
129
    if (ioctl(dev->nFileNo, PCIVME_INIT_HARDWARE, &init) < 0)
130
    {
130
    {
131
        dev->nLastError = errno;
131
        dev->nLastError = errno;
132
        printf("initHardware:err=%d %s\n" , errno,  strerror(errno) );
132
        printf("initHardware:err=%d %s\n" , errno,  strerror(errno) );
133
        return errno;
133
        return errno;
134
    }
134
    }
135
 
135
 
136
    return 0;
136
    return 0;
137
}
137
}
138
 
138
 
139
static int deInitHardware(VMEMM_DEVICE *dev)
139
static int deInitHardware(VMEMM_DEVICE *dev)
140
{
140
{
141
    PCIVME_INIT_COMMAND deinit;
141
    PCIVME_INIT_COMMAND deinit;
142
 
142
 
143
    deinit.sVie[0].bDestination = STOP;
143
    deinit.sVie[0].bDestination = STOP;
144
    deinit.sVie[0].bAccessType  =
144
    deinit.sVie[0].bAccessType  =
145
    deinit.sVie[0].dwValue      =
145
    deinit.sVie[0].dwValue      =
146
    deinit.sVie[0].wOffset      = 0;
146
    deinit.sVie[0].wOffset      = 0;
147
 
147
 
148
    if (ioctl(dev->nFileNo, PCIVME_DEINIT_HARDWARE, &deinit) < 0)
148
    if (ioctl(dev->nFileNo, PCIVME_DEINIT_HARDWARE, &deinit) < 0)
149
    {
149
    {
150
        dev->nLastError = errno;
150
        dev->nLastError = errno;
151
        printf("deInitHardware:err=%d %s\n" , errno,  strerror(errno) );
151
        printf("deInitHardware:err=%d %s\n" , errno,  strerror(errno) );
152
        return errno;
152
        return errno;
153
    }
153
    }
154
 
154
 
155
    return 0;
155
    return 0;
156
}
156
}
157
 
157
 
158
int VMEopen(const char *cszDeviceName, unsigned char ubAddressModifier, int *pnHandle)
158
int VMEopen(const char *cszDeviceName, unsigned char ubAddressModifier, int *pnHandle)
159
{
159
{
160
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)NULL;
160
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)NULL;
161
    int error;
161
    int error;
162
 
162
 
163
    *pnHandle = 0;
163
    *pnHandle = 0;
164
 
164
 
165
    dev = (VMEMM_DEVICE *)malloc(sizeof(*dev));
165
    dev = (VMEMM_DEVICE *)malloc(sizeof(*dev));
166
    if (!dev)
166
    if (!dev)
167
        return errno;
167
        return errno;
168
 
168
 
169
    dev->nFileNo = open(cszDeviceName, O_RDWR);
169
    dev->nFileNo = open(cszDeviceName, O_RDWR);
170
    printf("VMEopen: dev->nFileNo %d size=%d %s\n" , dev->nFileNo,sizeof(*dev),  cszDeviceName );
170
    printf("VMEopen: dev->nFileNo %d size=%d %s\n" , dev->nFileNo,sizeof(*dev),  cszDeviceName );
171
    if (dev->nFileNo == -1)
171
    if (dev->nFileNo == -1)
172
    {
172
    {
173
        error = errno;
173
        error = errno;
174
        printf("VMEopen:err=%d %s\n" , error,  strerror(error) );
174
        printf("VMEopen:err=%d %s\n" , error,  strerror(error) );
175
        free(dev);
175
        free(dev);
176
        return error;
176
        return error;
177
    }
177
    }
178
 
178
 
179
    dev->cAddressModifier = ubAddressModifier;
179
    dev->cAddressModifier = ubAddressModifier;
180
    *pnHandle             = (int)dev;
180
    *pnHandle             = (int)dev;
181
 
181
 
182
    error = initHardware(dev);
182
    error = initHardware(dev);
183
    if (error)
183
    if (error)
184
        return error;
184
        return error;
185
 
185
 
186
    dev->nLastError = 0;
186
    dev->nLastError = 0;
187
 
187
 
188
    return setAccessProperties(*pnHandle, dev->cAddressModifier, BYTE_ACCESS); // set access properties to default
188
    return setAccessProperties(*pnHandle, dev->cAddressModifier, BYTE_ACCESS); // set access properties to default
189
}
189
}
190
 
190
 
191
int VMEinit(const char *cszDeviceName, unsigned short nVMEMM, unsigned char ubAddressModifier, int *pnHandle)
191
int VMEinit(const char *cszDeviceName, unsigned short nVMEMM, unsigned char ubAddressModifier, int *pnHandle)
192
{
192
{
193
    char *szLocalDeviceName = szDeviceName(cszDeviceName, nVMEMM);
193
    char *szLocalDeviceName = szDeviceName(cszDeviceName, nVMEMM);
194
 
194
 
195
    return VMEopen(szLocalDeviceName, ubAddressModifier, pnHandle);
195
    return VMEopen(szLocalDeviceName, ubAddressModifier, pnHandle);
196
}
196
}
197
 
197
 
198
int setAccessProperties(int nHandle, unsigned char bModifier, unsigned char bAccessType)
198
int setAccessProperties(int nHandle, unsigned char bModifier, unsigned char bAccessType)
199
{
199
{
200
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
200
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
201
 
201
 
202
    PCIVME_ACCESS_COMMAND access_command;
202
    PCIVME_ACCESS_COMMAND access_command;
203
               
203
               
204
    access_command.bAccessType =
204
    access_command.bAccessType =
205
    access_command.bIncrement  = bAccessType;  // increment and accessType are the same
205
    access_command.bIncrement  = bAccessType;  // increment and accessType are the same
206
    access_command.bModifier   = bModifier;
206
    access_command.bModifier   = bModifier;
207
 
207
 
208
    if (ioctl(dev->nFileNo, PCIVME_SET_ACCESS_PARA, &access_command) < 0)
208
    if (ioctl(dev->nFileNo, PCIVME_SET_ACCESS_PARA, &access_command) < 0)
209
    {
209
    {
210
        dev->nLastError = errno;
210
        dev->nLastError = errno;
211
        printf("setAccessProperties:err=%d %s\n" , errno,  strerror(errno) );
211
        printf("setAccessProperties:err=%d %s\n" , errno,  strerror(errno) );
212
        return errno;
212
        return errno;
213
    }
213
    }
214
 
214
 
215
    dev->cAddressModifier = bModifier;
215
    dev->cAddressModifier = bModifier;
216
    dev->cAccessWidth     = bAccessType;
216
    dev->cAccessWidth     = bAccessType;
217
 
217
 
218
    return 0;
218
    return 0;
219
}
219
}
220
 
220
 
221
int VMEread(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
221
int VMEread(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
222
{
222
{
223
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
223
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
224
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
224
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
225
    ssize_t result;
225
    ssize_t result;
226
    int error;
226
    int error;
227
    long pos;
227
    long pos;
228
 
228
 
229
    printf("VMEread:  AW 0x%0x 0x%0x  , AM 0x%0x \n", dev->cAccessWidth, ubAccessWidth, dev->cAddressModifier);
229
//    printf("VMEread:  AW 0x%0x 0x%0x  , AM 0x%0x \n", dev->cAccessWidth, ubAccessWidth, dev->cAddressModifier);
230
    if (dev->cAccessWidth != ubAccessWidth)
230
    if (dev->cAccessWidth != ubAccessWidth)
231
    {
231
    {
232
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
232
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
233
            return error;
233
            return error;
234
    }
234
    }
235
    pos = lseek(dev->nFileNo, ulAddress, SEEK_SET);
235
    pos = lseek(dev->nFileNo, ulAddress, SEEK_SET);
236
   
236
   
237
    if ( pos < 0){
237
    if ( pos < 0){
238
        printf("VMEread: pos=0x%08lx dev->nFileNo=%d ADDR=0x%08lx %s\n",pos, dev->nFileNo, ulAddress, strerror(errno));
238
        printf("VMEread: pos=0x%08lx dev->nFileNo=%d ADDR=0x%08lx %s\n",pos, dev->nFileNo, ulAddress, strerror(errno));
239
        switch (errno){
239
        switch (errno){
240
          case EBADF:printf("errno =EBADF\n");break;
240
          case EBADF:printf("errno =EBADF\n");break;
241
          case EINVAL:printf("errno =EINVAL\n");break;
241
          case EINVAL:printf("errno =EINVAL\n");break;
242
          case EOVERFLOW:printf("errno =EOVERFLOW\n");break;
242
          case EOVERFLOW:printf("errno =EOVERFLOW\n");break;
243
          case ESPIPE:printf("errno =ESPIPE\n");break;
243
          case ESPIPE:printf("errno =ESPIPE\n");break;
244
          case ENXIO:printf("errno =ENXIO\n");break;
244
          case ENXIO:printf("errno =ENXIO\n");break;
245
        }
245
        }
246
        //return errno;
246
        //return errno;
247
    }
247
    }
248
 
248
 
249
   
249
   
250
    result = read(dev->nFileNo, pvBuffer, count);
250
    result = read(dev->nFileNo, pvBuffer, count);
251
    printf("VMEread: read %d dev->nFileNo=%d err=%d %s\n",count, dev->nFileNo, errno, strerror(errno));
251
//    printf("VMEread: read %d dev->nFileNo=%d err=%d %s\n",count, dev->nFileNo, errno, strerror(errno));
252
    if (result != count)
252
    if (result != count)
253
    {
253
    {
254
        if (result < 0)
254
        if (result < 0)
255
        {
255
        {
256
            dev->nLastError = errno;
256
            dev->nLastError = errno;
257
            return errno;
257
            return errno;
258
        }
258
        }
259
        else
259
        else
260
            return EFAULT;
260
            return EFAULT;
261
    }
261
    }
262
 
262
 
263
    return 0;
263
    return 0;
264
}
264
}
265
 
265
 
266
int VMEwrite(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
266
int VMEwrite(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
267
{
267
{
268
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
268
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
269
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
269
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
270
    ssize_t result;
270
    ssize_t result;
271
    int error;
271
    int error;
272
    long pos;
272
    long pos;
273
 
273
 
274
    printf("VMEwrite:  AW 0x%0x 0x%0x  , AM 0x%0x \n", dev->cAccessWidth, ubAccessWidth, dev->cAddressModifier);
274
//    printf("VMEwrite:  AW 0x%0x 0x%0x  , AM 0x%0x \n", dev->cAccessWidth, ubAccessWidth, dev->cAddressModifier);
275
    if (dev->cAccessWidth != ubAccessWidth)
275
    if (dev->cAccessWidth != ubAccessWidth)
276
    {
276
    {
277
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
277
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
278
            return error;
278
            return error;
279
    }
279
    }
280
 
280
 
281
    pos = lseek(dev->nFileNo, ulAddress, SEEK_SET);
281
    pos = lseek(dev->nFileNo, ulAddress, SEEK_SET);
282
    if (pos < 0){
282
    if (pos < 0){
283
        printf("VMEwrite: pos=0x%08lx  dev->nFileNo=%d ADDR=0x%08lx %s\n",pos, dev->nFileNo, ulAddress, strerror(errno));
283
        printf("VMEwrite: pos=0x%08lx  dev->nFileNo=%d ADDR=0x%08lx %s\n",pos, dev->nFileNo, ulAddress, strerror(errno));
284
        switch (errno){
284
        switch (errno){
285
          case EBADF:printf("errno =EBADF\n");break;
285
          case EBADF:printf("errno =EBADF\n");break;
286
          case EINVAL:printf("errno =EINVAL\n");break;
286
          case EINVAL:printf("errno =EINVAL\n");break;
287
          case EOVERFLOW:printf("errno =EOVERFLOW\n");break;
287
          case EOVERFLOW:printf("errno =EOVERFLOW\n");break;
288
          case ESPIPE:printf("errno =ESPIPE\n");break;
288
          case ESPIPE:printf("errno =ESPIPE\n");break;
289
          case ENXIO:printf("errno =ENXIO\n");break;
289
          case ENXIO:printf("errno =ENXIO\n");break;
290
        }
290
        }
291
        //return errno;
291
        //return errno;
292
    }
292
    }
293
    result = write(dev->nFileNo, pvBuffer, count);
293
    result = write(dev->nFileNo, pvBuffer, count);
294
    printf("VMEwrite: write %d dev->nFileNo=%d err=%d %s\n",count, dev->nFileNo,errno, strerror(errno));
294
//    printf("VMEwrite: write %d dev->nFileNo=%d err=%d %s\n",count, dev->nFileNo,errno, strerror(errno));
295
    if (result != count)
295
    if (result != count)
296
    {
296
    {
297
        if (result < 0)
297
        if (result < 0)
298
        {
298
        {
299
            dev->nLastError = errno;
299
            dev->nLastError = errno;
300
           
300
           
301
            return errno;
301
            return errno;
302
        }
302
        }
303
        else
303
        else
304
            return EFAULT;
304
            return EFAULT;
305
    }
305
    }
306
 
306
 
307
    return 0;
307
    return 0;
308
}
308
}
309
 
309
 
310
int VMEaccessVIC(int nHandle, unsigned char ubAccessMode, unsigned short uwAddress, unsigned char *ubContent)
310
int VMEaccessVIC(int nHandle, unsigned char ubAccessMode, unsigned short uwAddress, unsigned char *ubContent)
311
{
311
{
312
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
312
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
313
    PCIVME_VIC68A_ACTION vic68a_action;
313
    PCIVME_VIC68A_ACTION vic68a_action;
314
 
314
 
315
    vic68a_action.bAccessMode      = ubAccessMode;
315
    vic68a_action.bAccessMode      = ubAccessMode;
316
    vic68a_action.bContent         = *ubContent;  
316
    vic68a_action.bContent         = *ubContent;  
317
    vic68a_action.wRegisterAddress = uwAddress;
317
    vic68a_action.wRegisterAddress = uwAddress;
318
 
318
 
319
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &vic68a_action) < 0)
319
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &vic68a_action) < 0)
320
    {
320
    {
321
        dev->nLastError = errno;
321
        dev->nLastError = errno;
322
        return errno;
322
        return errno;
323
    }
323
    }
324
 
324
 
325
    *ubContent = vic68a_action.bContent;
325
    *ubContent = vic68a_action.bContent;
326
 
326
 
327
    return 0;
327
    return 0;
328
}
328
}
329
 
329
 
330
int VMEreset(int nHandle)
330
int VMEreset(int nHandle)
331
{
331
{
332
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
332
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
333
    PCIVME_RESET_COMMAND reset_command;
333
    PCIVME_RESET_COMMAND reset_command;
334
    int i = 10;
334
    int i = 10;
335
 
335
 
336
    reset_command.bCommand = GLOBAL_RESET_CMD;
336
    reset_command.bCommand = GLOBAL_RESET_CMD;
337
    reset_command.bResult  = 0xff;  
337
    reset_command.bResult  = 0xff;  
338
 
338
 
339
    if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
339
    if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
340
    {
340
    {
341
        dev->nLastError = errno;
341
        dev->nLastError = errno;
342
        return errno;
342
        return errno;
343
    }
343
    }
344
 
344
 
345
    do
345
    do
346
    {
346
    {
347
        usleep(100);
347
        usleep(100);
348
        reset_command.bCommand = POLL_RESET_CMD;
348
        reset_command.bCommand = POLL_RESET_CMD;
349
        reset_command.bResult  = 0xff;  
349
        reset_command.bResult  = 0xff;  
350
   
350
   
351
        if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
351
        if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
352
        {
352
        {
353
            dev->nLastError = errno;
353
            dev->nLastError = errno;
354
            return errno;
354
            return errno;
355
        }
355
        }
356
    } while ((reset_command.bResult) && (i--));
356
    } while ((reset_command.bResult) && (i--));
357
 
357
 
358
    if (!i)
358
    if (!i)
359
        return ETIME;
359
        return ETIME;
360
 
360
 
361
    dev->nLastError = 0;
361
    dev->nLastError = 0;
362
 
362
 
363
    return 0;
363
    return 0;
364
}
364
}
365
 
365
 
366
int VMETAS(int nHandle, unsigned long ulAddress, unsigned char *ubResult)
366
int VMETAS(int nHandle, unsigned long ulAddress, unsigned char *ubResult)
367
{
367
{
368
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
368
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
369
    PCIVME_TAS_STRUCT tas;
369
    PCIVME_TAS_STRUCT tas;
370
 
370
 
371
    tas.bContent  = *ubResult;
371
    tas.bContent  = *ubResult;
372
    tas.bModifier = dev->cAddressModifier;  
372
    tas.bModifier = dev->cAddressModifier;  
373
    tas.dwAddress = ulAddress;
373
    tas.dwAddress = ulAddress;
374
 
374
 
375
    if (ioctl(dev->nFileNo, PCIVME_TAS, &tas) < 0)
375
    if (ioctl(dev->nFileNo, PCIVME_TAS, &tas) < 0)
376
    {
376
    {
377
        dev->nLastError = errno;
377
        dev->nLastError = errno;
378
        return errno;
378
        return errno;
379
    }
379
    }
380
 
380
 
381
    *ubResult = tas.bContent;
381
    *ubResult = tas.bContent;
382
 
382
 
383
    return 0;
383
    return 0;
384
}
384
}
385
 
385
 
386
int VMEinterrupt(int nHandle, unsigned char *ubVector)
386
int VMEinterrupt(int nHandle, unsigned char *ubVector)
387
{
387
{
388
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
388
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
389
        PCIVME_VECTOR_LEVEL ubLocalVector;
389
        PCIVME_VECTOR_LEVEL ubLocalVector;
390
 
390
 
391
    if (ioctl(dev->nFileNo, PCIVME_READ_VECTOR_POLL, &ubLocalVector) < 0)
391
    if (ioctl(dev->nFileNo, PCIVME_READ_VECTOR_POLL, &ubLocalVector) < 0)
392
    {
392
    {
393
        dev->nLastError = errno;
393
        dev->nLastError = errno;
394
        return errno;
394
        return errno;
395
    }
395
    }
396
 
396
 
397
    *ubVector = (__u8)ubLocalVector.dwStatusID;
397
    *ubVector = (__u8)ubLocalVector.dwStatusID;
398
 
398
 
399
    return 0;
399
    return 0;
400
}
400
}
401
 
401
 
402
int VMEsysfailGet(int nHandle, BOOLEAN *bResult)
402
int VMEsysfailGet(int nHandle, BOOLEAN *bResult)
403
{
403
{
404
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
404
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
405
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
405
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
406
 
406
 
407
        sAction.wRegisterAddress = EGICR;
407
        sAction.wRegisterAddress = EGICR;
408
        sAction.bAccessMode      = VIC68A_READ;
408
        sAction.bAccessMode      = VIC68A_READ;
409
        sAction.bContent         = 0;
409
        sAction.bContent         = 0;
410
 
410
 
411
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
411
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
412
    {
412
    {
413
        dev->nLastError = errno;
413
        dev->nLastError = errno;
414
        return errno;
414
        return errno;
415
    }
415
    }
416
 
416
 
417
        *bResult = (sAction.bContent & 0x08) ? FALSE : TRUE;
417
        *bResult = (sAction.bContent & 0x08) ? FALSE : TRUE;
418
 
418
 
419
    return 0;
419
    return 0;
420
}
420
}
421
 
421
 
422
int VMEsysfailSet(int nHandle, BOOLEAN bForce)
422
int VMEsysfailSet(int nHandle, BOOLEAN bForce)
423
{
423
{
424
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
424
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
425
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
425
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
426
 
426
 
427
        sAction.wRegisterAddress = ICR7;
427
        sAction.wRegisterAddress = ICR7;
428
        sAction.bAccessMode      = (bForce == TRUE) ? VIC68A_AND : VIC68A_OR;
428
        sAction.bAccessMode      = (bForce == TRUE) ? VIC68A_AND : VIC68A_OR;
429
        sAction.bContent         = (bForce == TRUE) ? 0x3F               : 0x80;
429
        sAction.bContent         = (bForce == TRUE) ? 0x3F               : 0x80;
430
 
430
 
431
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
431
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
432
    {
432
    {
433
        dev->nLastError = errno;
433
        dev->nLastError = errno;
434
        return errno;
434
        return errno;
435
    }
435
    }
436
 
436
 
437
    return 0;
437
    return 0;
438
}
438
}
439
 
439
 
440
int VMEerror(int nHandle)
440
int VMEerror(int nHandle)
441
{
441
{
442
    __u8 ubVector;
442
    __u8 ubVector;
443
 
443
 
444
    VMEinterrupt(nHandle, &ubVector);
444
    VMEinterrupt(nHandle, &ubVector);
445
 
445
 
446
    if (ubVector == 7)
446
    if (ubVector == 7)
447
        return EFAULT;  // it's a bus error
447
        return EFAULT;  // it's a bus error
448
    else
448
    else
449
        return 0;
449
        return 0;
450
}
450
}
451
 
451
 
452
int VMEclose(int nHandle)
452
int VMEclose(int nHandle)
453
{
453
{
454
    int error = 0;
454
    int error = 0;
455
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
455
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
456
 
456
 
457
    if (dev != (VMEMM_DEVICE *)NULL)
457
    if (dev != (VMEMM_DEVICE *)NULL)
458
    {
458
    {
459
        deInitHardware(dev);
459
        deInitHardware(dev);
460
 
460
 
461
        if (dev->nFileNo != -1)
461
        if (dev->nFileNo != -1)
462
            close(dev->nFileNo);
462
            close(dev->nFileNo);
463
        else
463
        else
464
            error = -EINVAL;
464
            error = -EINVAL;
465
 
465
 
466
        free(dev);
466
        free(dev);
467
    }
467
    }
468
 
468
 
469
    return error;
469
    return error;
470
}
470
}
471
 
471
 
472
int VMEcontrolInterrupt(int nHandle, BOOLEAN *bEnable)
472
int VMEcontrolInterrupt(int nHandle, BOOLEAN *bEnable)
473
{
473
{
474
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
474
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
475
        PCIVME_IRQ_CONTROL  control;
475
        PCIVME_IRQ_CONTROL  control;
476
 
476
 
477
    control.bEnable = *bEnable;
477
    control.bEnable = *bEnable;
478
 
478
 
479
    if (ioctl(dev->nFileNo, PCIVME_CONTROL_INTERRUPTS, &control) < 0)
479
    if (ioctl(dev->nFileNo, PCIVME_CONTROL_INTERRUPTS, &control) < 0)
480
    {
480
    {
481
        dev->nLastError = errno;
481
        dev->nLastError = errno;
482
        return errno;
482
        return errno;
483
    }
483
    }
484
 
484
 
485
    // status of interrupt enable before set
485
    // status of interrupt enable before set
486
    *bEnable = control.bEnable;
486
    *bEnable = control.bEnable;
487
 
487
 
488
    return 0;
488
    return 0;
489
}
489
}
490
 
490
 
491
int GetLastError(int nHandle)
491
int GetLastError(int nHandle)
492
{
492
{
493
    VMEMM_DEVICE *dev  = (VMEMM_DEVICE *)nHandle;
493
    VMEMM_DEVICE *dev  = (VMEMM_DEVICE *)nHandle;
494
    int nLocalError;
494
    int nLocalError;
495
 
495
 
496
    nLocalError = dev->nLastError;
496
    nLocalError = dev->nLastError;
497
    dev->nLastError = 0;
497
    dev->nLastError = 0;
498
 
498
 
499
    return nLocalError;
499
    return nLocalError;
500
}
500
}
501
 
501
 
502
 
502
 
503
 
503