Subversion Repositories f9daq

Rev

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

Rev 9 Rev 11
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
        return errno;
133
        return errno;
133
    }
134
    }
134
 
135
 
135
    return 0;
136
    return 0;
136
}
137
}
137
 
138
 
138
static int deInitHardware(VMEMM_DEVICE *dev)
139
static int deInitHardware(VMEMM_DEVICE *dev)
139
{
140
{
140
    PCIVME_INIT_COMMAND deinit;
141
    PCIVME_INIT_COMMAND deinit;
141
 
142
 
142
    deinit.sVie[0].bDestination = STOP;
143
    deinit.sVie[0].bDestination = STOP;
143
    deinit.sVie[0].bAccessType  =
144
    deinit.sVie[0].bAccessType  =
144
    deinit.sVie[0].dwValue      =
145
    deinit.sVie[0].dwValue      =
145
    deinit.sVie[0].wOffset      = 0;
146
    deinit.sVie[0].wOffset      = 0;
146
 
147
 
147
    if (ioctl(dev->nFileNo, PCIVME_DEINIT_HARDWARE, &deinit) < 0)
148
    if (ioctl(dev->nFileNo, PCIVME_DEINIT_HARDWARE, &deinit) < 0)
148
    {
149
    {
149
        dev->nLastError = errno;
150
        dev->nLastError = errno;
-
 
151
        printf("deInitHardware:err=%d %s\n" , errno,  strerror(errno) );
150
        return errno;
152
        return errno;
151
    }
153
    }
152
 
154
 
153
    return 0;
155
    return 0;
154
}
156
}
155
 
157
 
156
int VMEopen(const char *cszDeviceName, unsigned char ubAddressModifier, int *pnHandle)
158
int VMEopen(const char *cszDeviceName, unsigned char ubAddressModifier, int *pnHandle)
157
{
159
{
158
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)NULL;
160
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)NULL;
159
    int error;
161
    int error;
160
 
162
 
161
    *pnHandle = 0;
163
    *pnHandle = 0;
162
 
164
 
163
    dev = (VMEMM_DEVICE *)malloc(sizeof(*dev));
165
    dev = (VMEMM_DEVICE *)malloc(sizeof(*dev));
164
    if (!dev)
166
    if (!dev)
165
        return errno;
167
        return errno;
166
 
168
 
167
    dev->nFileNo = open(cszDeviceName, O_RDWR);
169
    dev->nFileNo = open(cszDeviceName, O_RDWR);
168
 
-
 
-
 
170
    printf("VMEopen: dev->nFileNo %d size=%d %s\n" , dev->nFileNo,sizeof(*dev),  cszDeviceName );
169
    if (dev->nFileNo == -1)
171
    if (dev->nFileNo == -1)
170
    {
172
    {
171
        error = errno;
173
        error = errno;
-
 
174
        printf("VMEopen:err=%d %s\n" , error,  strerror(error) );
172
        free(dev);
175
        free(dev);
173
        return error;
176
        return error;
174
    }
177
    }
175
 
178
 
176
    dev->cAddressModifier = ubAddressModifier;
179
    dev->cAddressModifier = ubAddressModifier;
177
    *pnHandle             = (int)dev;
180
    *pnHandle             = (int)dev;
178
 
181
 
179
    error = initHardware(dev);
182
    error = initHardware(dev);
180
    if (error)
183
    if (error)
181
        return error;
184
        return error;
182
 
185
 
183
    dev->nLastError = 0;
186
    dev->nLastError = 0;
184
 
187
 
185
    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
186
}
189
}
187
 
190
 
188
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)
189
{
192
{
190
    char *szLocalDeviceName = szDeviceName(cszDeviceName, nVMEMM);
193
    char *szLocalDeviceName = szDeviceName(cszDeviceName, nVMEMM);
191
 
194
 
192
    return VMEopen(szLocalDeviceName, ubAddressModifier, pnHandle);
195
    return VMEopen(szLocalDeviceName, ubAddressModifier, pnHandle);
193
}
196
}
194
 
197
 
195
int setAccessProperties(int nHandle, unsigned char bModifier, unsigned char bAccessType)
198
int setAccessProperties(int nHandle, unsigned char bModifier, unsigned char bAccessType)
196
{
199
{
197
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
200
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
198
 
201
 
199
    PCIVME_ACCESS_COMMAND access_command;
202
    PCIVME_ACCESS_COMMAND access_command;
200
               
203
               
201
    access_command.bAccessType =
204
    access_command.bAccessType =
202
    access_command.bIncrement  = bAccessType;  // increment and accessType are the same
205
    access_command.bIncrement  = bAccessType;  // increment and accessType are the same
203
    access_command.bModifier   = bModifier;
206
    access_command.bModifier   = bModifier;
204
 
207
 
205
    if (ioctl(dev->nFileNo, PCIVME_SET_ACCESS_PARA, &access_command) < 0)
208
    if (ioctl(dev->nFileNo, PCIVME_SET_ACCESS_PARA, &access_command) < 0)
206
    {
209
    {
207
        dev->nLastError = errno;
210
        dev->nLastError = errno;
-
 
211
        printf("setAccessProperties:err=%d %s\n" , errno,  strerror(errno) );
208
        return errno;
212
        return errno;
209
    }
213
    }
210
 
214
 
211
    dev->cAddressModifier = bModifier;
215
    dev->cAddressModifier = bModifier;
212
    dev->cAccessWidth     = bAccessType;
216
    dev->cAccessWidth     = bAccessType;
213
 
217
 
214
    return 0;
218
    return 0;
215
}
219
}
216
 
220
 
217
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)
218
{
222
{
219
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
223
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
220
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
224
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
221
    ssize_t result;
225
    ssize_t result;
222
    int error;
226
    int error;
-
 
227
    long pos;
223
 
228
 
-
 
229
    printf("VMEread:  AW 0x%0x 0x%0x  , AM 0x%0x \n", dev->cAccessWidth, ubAccessWidth, dev->cAddressModifier);
224
    if (dev->cAccessWidth != ubAccessWidth)
230
    if (dev->cAccessWidth != ubAccessWidth)
225
    {
231
    {
226
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
232
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
227
            return error;
233
            return error;
-
 
234
    }
-
 
235
    pos = lseek(dev->nFileNo, ulAddress, SEEK_SET);
-
 
236
   
-
 
237
    if ( pos < 0){
-
 
238
        printf("VMEread: pos=0x%08lx dev->nFileNo=%d ADDR=0x%08lx %s\n",pos, dev->nFileNo, ulAddress, strerror(errno));
-
 
239
        switch (errno){
-
 
240
          case EBADF:printf("errno =EBADF\n");break;
-
 
241
          case EINVAL:printf("errno =EINVAL\n");break;
-
 
242
          case EOVERFLOW:printf("errno =EOVERFLOW\n");break;
-
 
243
          case ESPIPE:printf("errno =ESPIPE\n");break;
-
 
244
          case ENXIO:printf("errno =ENXIO\n");break;
-
 
245
        }
-
 
246
        //return errno;
228
    }
247
    }
229
 
248
 
230
    if (lseek(dev->nFileNo, ulAddress, SEEK_SET) < 0)
-
 
231
        return errno;
-
 
232
 
249
   
233
    result = read(dev->nFileNo, pvBuffer, count);
250
    result = read(dev->nFileNo, pvBuffer, count);
234
 
-
 
-
 
251
    printf("VMEread: read %d dev->nFileNo=%d err=%d %s\n",count, dev->nFileNo, errno, strerror(errno));
235
    if (result != count)
252
    if (result != count)
236
    {
253
    {
237
        if (result < 0)
254
        if (result < 0)
238
        {
255
        {
239
            dev->nLastError = errno;
256
            dev->nLastError = errno;
240
            return errno;
257
            return errno;
241
        }
258
        }
242
        else
259
        else
243
            return EFAULT;
260
            return EFAULT;
244
    }
261
    }
245
 
262
 
246
    return 0;
263
    return 0;
247
}
264
}
248
 
265
 
249
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)
250
{
267
{
251
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
268
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
252
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
269
    size_t count      = (size_t)(ulElementCount * ubAccessWidth);
253
    ssize_t result;
270
    ssize_t result;
254
    int error;
271
    int error;
-
 
272
    long pos;
255
 
273
 
-
 
274
    printf("VMEwrite:  AW 0x%0x 0x%0x  , AM 0x%0x \n", dev->cAccessWidth, ubAccessWidth, dev->cAddressModifier);
256
    if (dev->cAccessWidth != ubAccessWidth)
275
    if (dev->cAccessWidth != ubAccessWidth)
257
    {
276
    {
258
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
277
        if ((error = setAccessProperties(nHandle, dev->cAddressModifier, ubAccessWidth)))
259
            return error;
278
            return error;
260
    }
279
    }
261
 
280
 
262
    if (lseek(dev->nFileNo, ulAddress, SEEK_SET) < 0)
281
    pos = lseek(dev->nFileNo, ulAddress, SEEK_SET);
-
 
282
    if (pos < 0){
-
 
283
        printf("VMEwrite: pos=0x%08lx  dev->nFileNo=%d ADDR=0x%08lx %s\n",pos, dev->nFileNo, ulAddress, strerror(errno));
-
 
284
        switch (errno){
-
 
285
          case EBADF:printf("errno =EBADF\n");break;
-
 
286
          case EINVAL:printf("errno =EINVAL\n");break;
-
 
287
          case EOVERFLOW:printf("errno =EOVERFLOW\n");break;
-
 
288
          case ESPIPE:printf("errno =ESPIPE\n");break;
-
 
289
          case ENXIO:printf("errno =ENXIO\n");break;
-
 
290
        }
263
        return errno;
291
        //return errno;
264
 
292
    }
265
    result = write(dev->nFileNo, pvBuffer, count);
293
    result = write(dev->nFileNo, pvBuffer, count);
266
 
-
 
-
 
294
    printf("VMEwrite: write %d dev->nFileNo=%d err=%d %s\n",count, dev->nFileNo,errno, strerror(errno));
267
    if (result != count)
295
    if (result != count)
268
    {
296
    {
269
        if (result < 0)
297
        if (result < 0)
270
        {
298
        {
271
            dev->nLastError = errno;
299
            dev->nLastError = errno;
-
 
300
           
272
            return errno;
301
            return errno;
273
        }
302
        }
274
        else
303
        else
275
            return EFAULT;
304
            return EFAULT;
276
    }
305
    }
277
 
306
 
278
    return 0;
307
    return 0;
279
}
308
}
280
 
309
 
281
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)
282
{
311
{
283
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
312
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
284
    PCIVME_VIC68A_ACTION vic68a_action;
313
    PCIVME_VIC68A_ACTION vic68a_action;
285
 
314
 
286
    vic68a_action.bAccessMode      = ubAccessMode;
315
    vic68a_action.bAccessMode      = ubAccessMode;
287
    vic68a_action.bContent         = *ubContent;  
316
    vic68a_action.bContent         = *ubContent;  
288
    vic68a_action.wRegisterAddress = uwAddress;
317
    vic68a_action.wRegisterAddress = uwAddress;
289
 
318
 
290
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &vic68a_action) < 0)
319
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &vic68a_action) < 0)
291
    {
320
    {
292
        dev->nLastError = errno;
321
        dev->nLastError = errno;
293
        return errno;
322
        return errno;
294
    }
323
    }
295
 
324
 
296
    *ubContent = vic68a_action.bContent;
325
    *ubContent = vic68a_action.bContent;
297
 
326
 
298
    return 0;
327
    return 0;
299
}
328
}
300
 
329
 
301
int VMEreset(int nHandle)
330
int VMEreset(int nHandle)
302
{
331
{
303
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
332
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
304
    PCIVME_RESET_COMMAND reset_command;
333
    PCIVME_RESET_COMMAND reset_command;
305
    int i = 10;
334
    int i = 10;
306
 
335
 
307
    reset_command.bCommand = GLOBAL_RESET_CMD;
336
    reset_command.bCommand = GLOBAL_RESET_CMD;
308
    reset_command.bResult  = 0xff;  
337
    reset_command.bResult  = 0xff;  
309
 
338
 
310
    if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
339
    if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
311
    {
340
    {
312
        dev->nLastError = errno;
341
        dev->nLastError = errno;
313
        return errno;
342
        return errno;
314
    }
343
    }
315
 
344
 
316
    do
345
    do
317
    {
346
    {
318
        usleep(100);
347
        usleep(100);
319
        reset_command.bCommand = POLL_RESET_CMD;
348
        reset_command.bCommand = POLL_RESET_CMD;
320
        reset_command.bResult  = 0xff;  
349
        reset_command.bResult  = 0xff;  
321
   
350
   
322
        if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
351
        if (ioctl(dev->nFileNo, PCIVME_RESET, &reset_command) < 0)
323
        {
352
        {
324
            dev->nLastError = errno;
353
            dev->nLastError = errno;
325
            return errno;
354
            return errno;
326
        }
355
        }
327
    } while ((reset_command.bResult) && (i--));
356
    } while ((reset_command.bResult) && (i--));
328
 
357
 
329
    if (!i)
358
    if (!i)
330
        return ETIME;
359
        return ETIME;
331
 
360
 
332
    dev->nLastError = 0;
361
    dev->nLastError = 0;
333
 
362
 
334
    return 0;
363
    return 0;
335
}
364
}
336
 
365
 
337
int VMETAS(int nHandle, unsigned long ulAddress, unsigned char *ubResult)
366
int VMETAS(int nHandle, unsigned long ulAddress, unsigned char *ubResult)
338
{
367
{
339
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
368
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
340
    PCIVME_TAS_STRUCT tas;
369
    PCIVME_TAS_STRUCT tas;
341
 
370
 
342
    tas.bContent  = *ubResult;
371
    tas.bContent  = *ubResult;
343
    tas.bModifier = dev->cAddressModifier;  
372
    tas.bModifier = dev->cAddressModifier;  
344
    tas.dwAddress = ulAddress;
373
    tas.dwAddress = ulAddress;
345
 
374
 
346
    if (ioctl(dev->nFileNo, PCIVME_TAS, &tas) < 0)
375
    if (ioctl(dev->nFileNo, PCIVME_TAS, &tas) < 0)
347
    {
376
    {
348
        dev->nLastError = errno;
377
        dev->nLastError = errno;
349
        return errno;
378
        return errno;
350
    }
379
    }
351
 
380
 
352
    *ubResult = tas.bContent;
381
    *ubResult = tas.bContent;
353
 
382
 
354
    return 0;
383
    return 0;
355
}
384
}
356
 
385
 
357
int VMEinterrupt(int nHandle, unsigned char *ubVector)
386
int VMEinterrupt(int nHandle, unsigned char *ubVector)
358
{
387
{
359
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
388
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
360
        PCIVME_VECTOR_LEVEL ubLocalVector;
389
        PCIVME_VECTOR_LEVEL ubLocalVector;
361
 
390
 
362
    if (ioctl(dev->nFileNo, PCIVME_READ_VECTOR_POLL, &ubLocalVector) < 0)
391
    if (ioctl(dev->nFileNo, PCIVME_READ_VECTOR_POLL, &ubLocalVector) < 0)
363
    {
392
    {
364
        dev->nLastError = errno;
393
        dev->nLastError = errno;
365
        return errno;
394
        return errno;
366
    }
395
    }
367
 
396
 
368
    *ubVector = (__u8)ubLocalVector.dwStatusID;
397
    *ubVector = (__u8)ubLocalVector.dwStatusID;
369
 
398
 
370
    return 0;
399
    return 0;
371
}
400
}
372
 
401
 
373
int VMEsysfailGet(int nHandle, BOOLEAN *bResult)
402
int VMEsysfailGet(int nHandle, BOOLEAN *bResult)
374
{
403
{
375
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
404
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
376
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
405
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
377
 
406
 
378
        sAction.wRegisterAddress = EGICR;
407
        sAction.wRegisterAddress = EGICR;
379
        sAction.bAccessMode      = VIC68A_READ;
408
        sAction.bAccessMode      = VIC68A_READ;
380
        sAction.bContent         = 0;
409
        sAction.bContent         = 0;
381
 
410
 
382
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
411
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
383
    {
412
    {
384
        dev->nLastError = errno;
413
        dev->nLastError = errno;
385
        return errno;
414
        return errno;
386
    }
415
    }
387
 
416
 
388
        *bResult = (sAction.bContent & 0x08) ? FALSE : TRUE;
417
        *bResult = (sAction.bContent & 0x08) ? FALSE : TRUE;
389
 
418
 
390
    return 0;
419
    return 0;
391
}
420
}
392
 
421
 
393
int VMEsysfailSet(int nHandle, BOOLEAN bForce)
422
int VMEsysfailSet(int nHandle, BOOLEAN bForce)
394
{
423
{
395
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
424
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
396
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
425
        PCIVME_VIC68A_ACTION sAction;    // structure to access vic chip
397
 
426
 
398
        sAction.wRegisterAddress = ICR7;
427
        sAction.wRegisterAddress = ICR7;
399
        sAction.bAccessMode      = (bForce == TRUE) ? VIC68A_AND : VIC68A_OR;
428
        sAction.bAccessMode      = (bForce == TRUE) ? VIC68A_AND : VIC68A_OR;
400
        sAction.bContent         = (bForce == TRUE) ? 0x3F               : 0x80;
429
        sAction.bContent         = (bForce == TRUE) ? 0x3F               : 0x80;
401
 
430
 
402
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
431
    if (ioctl(dev->nFileNo, PCIVME_ACCESS_VIC68A, &sAction) < 0)
403
    {
432
    {
404
        dev->nLastError = errno;
433
        dev->nLastError = errno;
405
        return errno;
434
        return errno;
406
    }
435
    }
407
 
436
 
408
    return 0;
437
    return 0;
409
}
438
}
410
 
439
 
411
int VMEerror(int nHandle)
440
int VMEerror(int nHandle)
412
{
441
{
413
    __u8 ubVector;
442
    __u8 ubVector;
414
 
443
 
415
    VMEinterrupt(nHandle, &ubVector);
444
    VMEinterrupt(nHandle, &ubVector);
416
 
445
 
417
    if (ubVector == 7)
446
    if (ubVector == 7)
418
        return EFAULT;  // it's a bus error
447
        return EFAULT;  // it's a bus error
419
    else
448
    else
420
        return 0;
449
        return 0;
421
}
450
}
422
 
451
 
423
int VMEclose(int nHandle)
452
int VMEclose(int nHandle)
424
{
453
{
425
    int error = 0;
454
    int error = 0;
426
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
455
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
427
 
456
 
428
    if (dev != (VMEMM_DEVICE *)NULL)
457
    if (dev != (VMEMM_DEVICE *)NULL)
429
    {
458
    {
430
        deInitHardware(dev);
459
        deInitHardware(dev);
431
 
460
 
432
        if (dev->nFileNo != -1)
461
        if (dev->nFileNo != -1)
433
            close(dev->nFileNo);
462
            close(dev->nFileNo);
434
        else
463
        else
435
            error = -EINVAL;
464
            error = -EINVAL;
436
 
465
 
437
        free(dev);
466
        free(dev);
438
    }
467
    }
439
 
468
 
440
    return error;
469
    return error;
441
}
470
}
442
 
471
 
443
int VMEcontrolInterrupt(int nHandle, BOOLEAN *bEnable)
472
int VMEcontrolInterrupt(int nHandle, BOOLEAN *bEnable)
444
{
473
{
445
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
474
    VMEMM_DEVICE *dev = (VMEMM_DEVICE *)nHandle;
446
        PCIVME_IRQ_CONTROL  control;
475
        PCIVME_IRQ_CONTROL  control;
447
 
476
 
448
    control.bEnable = *bEnable;
477
    control.bEnable = *bEnable;
449
 
478
 
450
    if (ioctl(dev->nFileNo, PCIVME_CONTROL_INTERRUPTS, &control) < 0)
479
    if (ioctl(dev->nFileNo, PCIVME_CONTROL_INTERRUPTS, &control) < 0)
451
    {
480
    {
452
        dev->nLastError = errno;
481
        dev->nLastError = errno;
453
        return errno;
482
        return errno;
454
    }
483
    }
455
 
484
 
456
    // status of interrupt enable before set
485
    // status of interrupt enable before set
457
    *bEnable = control.bEnable;
486
    *bEnable = control.bEnable;
458
 
487
 
459
    return 0;
488
    return 0;
460
}
489
}
461
 
490
 
462
int GetLastError(int nHandle)
491
int GetLastError(int nHandle)
463
{
492
{
464
    VMEMM_DEVICE *dev  = (VMEMM_DEVICE *)nHandle;
493
    VMEMM_DEVICE *dev  = (VMEMM_DEVICE *)nHandle;
465
    int nLocalError;
494
    int nLocalError;
466
 
495
 
467
    nLocalError = dev->nLastError;
496
    nLocalError = dev->nLastError;
468
    dev->nLastError = 0;
497
    dev->nLastError = 0;
469
 
498
 
470
    return nLocalError;
499
    return nLocalError;
471
}
500
}
472
 
501
 
473
 
502
 
474
 
503