3
functions to retrieve kernel data
5
COMEDILIB - Linux Control and Measurement Device Interface Library
6
Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Lesser General Public
10
License as published by the Free Software Foundation, version 2.1
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Lesser General Public License for more details.
18
You should have received a copy of the GNU Lesser General Public
19
License along with this library; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27
#include <sys/types.h>
31
#include <sys/ioctl.h>
35
#include "libinternal.h"
38
/* these functions download information from the comedi module. */
40
static int do_test_for_cmd(comedi_t *dev,unsigned int subdevice);
41
static int do_test_for_insn(comedi_t *dev);
42
static int do_test_for_insnlist(comedi_t *dev);
43
static int do_test_for_insn_bits(comedi_t *dev,unsigned int subdevice);
46
int get_subdevices(comedi_t *it)
54
s=malloc(sizeof(comedi_subdinfo)*it->n_subdevices);
57
ret = comedi_ioctl(it->fd, COMEDI_SUBDINFO, (unsigned long)s);
60
r=it->subdevices=realloc(it->subdevices,
61
sizeof(subdevice)*it->n_subdevices);
63
memset(r,0,sizeof(subdevice)*it->n_subdevices);
65
it->has_insnlist_ioctl = do_test_for_insnlist(it);
66
it->has_insn_ioctl = do_test_for_insn(it);
67
for(i=0;i<it->n_subdevices;i++){
68
r[i].type = s[i].type;
69
if(r[i].type==COMEDI_SUBD_UNUSED)continue;
70
r[i].n_chan = s[i].n_chan;
71
r[i].subd_flags = s[i].subd_flags;
72
r[i].timer_type = s[i].timer_type;
73
r[i].len_chanlist = s[i].len_chanlist;
74
r[i].maxdata = s[i].maxdata;
75
r[i].flags = s[i].flags;
76
r[i].range_type = s[i].range_type;
78
if(r[i].subd_flags&SDF_FLAGS){
79
r[i].flags_list=malloc(sizeof(*r[i].flags_list)*r[i].n_chan);
80
debug_ptr(r[i].flags_list);
82
if(r[i].subd_flags&SDF_MAXDATA){
83
r[i].maxdata_list=malloc(sizeof(*r[i].maxdata_list)*r[i].n_chan);
84
debug_ptr(r[i].maxdata_list);
86
if(r[i].subd_flags&SDF_RANGETYPE){
87
r[i].range_type_list=malloc(sizeof(*r[i].range_type_list)*r[i].n_chan);
88
debug_ptr(r[i].range_type_list);
91
ci.flaglist = r[i].flags_list;
92
ci.rangelist = r[i].range_type_list;
93
ci.maxdata_list = r[i].maxdata_list;
94
ret = comedi_ioctl(it->fd, COMEDI_CHANINFO, (unsigned long)&ci);
97
if(r[i].subd_flags&SDF_RANGETYPE){
98
r[i].rangeinfo_list=malloc(sizeof(*r[i].rangeinfo_list)*r[i].n_chan);
99
debug_ptr(r[i].rangeinfo_list);
100
for(j=0;j<r[i].n_chan;j++){
101
r[i].rangeinfo_list[j]=get_rangeinfo(it->fd,r[i].range_type_list[j]);
104
r[i].rangeinfo=get_rangeinfo(it->fd,r[i].range_type);
107
r[i].has_cmd = do_test_for_cmd(it,i);
108
if(it->has_insnlist_ioctl){
109
r[i].has_insn_bits = do_test_for_insn_bits(it,i);
111
r[i].has_insn_bits = 0;
120
comedi_range *get_rangeinfo(int fd,unsigned int range_type)
128
kr=malloc(sizeof(comedi_krange)*RANGE_LENGTH(range_type));
129
r=malloc(sizeof(comedi_range)*RANGE_LENGTH(range_type));
131
ri.range_type = range_type;
133
ret = comedi_ioctl(fd, COMEDI_RANGEINFO, (unsigned long)&ri);
135
fprintf(stderr,"ioctl(%d,COMEDI_RANGEINFO,0x%08x,%p)\n",fd,range_type,kr);
138
for(i=0;i<RANGE_LENGTH(range_type);i++){
139
r[i].min=kr[i].min*1e-6;
140
r[i].max=kr[i].max*1e-6;
141
r[i].unit=kr[i].flags;
149
/* some command testing */
151
static int do_test_for_cmd(comedi_t *dev,unsigned int subdevice)
153
/* SDF_CMD was added in 0.7.57 */
154
if(dev->devinfo.version_code >= COMEDI_VERSION_CODE(0,7,57)){
155
if(dev->subdevices[subdevice].subd_flags & SDF_CMD)
162
memset(&it,0,sizeof(it));
164
it.subdev = subdevice;
165
it.start_src = TRIG_ANY;
166
it.scan_begin_src = TRIG_ANY;
167
it.convert_src = TRIG_ANY;
168
it.scan_end_src = TRIG_ANY;
169
it.stop_src = TRIG_ANY;
171
ret = comedi_ioctl(dev->fd, COMEDI_CMDTEST, (unsigned long)&it);
173
if(ret<0 && errno==EIO){
177
fprintf(stderr,"BUG in do_test_for_cmd()\n");
184
static int do_test_for_insnlist(comedi_t *dev)
191
memset(&insn,0,sizeof(insn));
196
insn.insn = INSN_GTOD;
200
ret = comedi_ioctl(dev->fd, COMEDI_INSNLIST, (unsigned long)&il);
204
fprintf(stderr,"BUG in do_test_for_insn()\n");
211
/* the COMEID_INSN ioctl was introduced in comedi-0.7.60 */
212
static int do_test_for_insn(comedi_t *dev)
219
memset(&insn,0,sizeof(insn));
224
insn.insn = INSN_GTOD;
228
ret = comedi_ioctl(dev->fd, COMEDI_INSN, (unsigned long)&insn);
232
fprintf(stderr,"BUG in do_test_for_insn()\n");
239
static int do_test_for_insn_bits(comedi_t *dev,unsigned int subdevice)
246
if(dev->subdevices[subdevice].maxdata != 1)
249
memset(&insn,0,sizeof(insn));
254
insn.insn = INSN_BITS;
257
insn.subdev = subdevice;
262
ret = comedi_do_insnlist(dev,&il);
264
if(ret<0 && (errno==EINVAL || errno==EIO)){
268
perror("BUG in do_test_for_insn_bits()\n");