Be a little more correct by setting CMDF_WRITE flag, in preparation
[comedilib.git] / lib / comedi.c
1 /*
2     lib/comedi.c
3     generic functions
4
5     COMEDILIB - Linux Control and Measurement Device Interface Library
6     Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
7
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
11     of the License.
12
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.
17
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
21     USA.
22 */
23
24 #include <stdio.h>
25 #include <math.h>
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <sys/ioctl.h>
32 #include <errno.h>
33 #include <string.h>
34
35 #include "libinternal.h"
36
37 INTERNAL int __comedi_init=0;
38
39 INTERNAL void initialize(void)
40 {
41         char *s;
42         
43         __comedi_init=1;
44
45         if( (s=getenv("COMEDILIB_LOGLEVEL")) ){
46                 __comedi_loglevel=strtol(s,NULL,0);
47                 COMEDILIB_DEBUG(3,"setting loglevel to %d\n",__comedi_loglevel);
48         }
49 }
50   
51 EXPORT_ALIAS_DEFAULT(_comedi_open,comedi_open,0.7.18);
52 comedi_t* _comedi_open(const char *fn)
53 {
54         comedi_t *it;
55
56         if(!__comedi_init)
57                 initialize();
58
59         if(!(it=malloc(sizeof(comedi_t))))
60                 goto cleanup;
61         memset(it,0,sizeof(comedi_t));
62
63         if((it->fd=open(fn,O_RDWR))<0){
64                 libc_error();
65                 goto cleanup;
66         }
67
68         if(comedi_ioctl(it->fd, COMEDI_DEVINFO, (unsigned long)&it->devinfo)<0)
69                 goto cleanup;
70
71         it->n_subdevices=it->devinfo.n_subdevs;
72
73         get_subdevices(it);
74
75         it->magic=COMEDILIB_MAGIC;
76
77         return it;
78 cleanup:
79         if(it)
80                 free(it);
81
82         return NULL;
83 }
84
85 EXPORT_ALIAS_DEFAULT(_comedi_close,comedi_close,0.7.18);
86 int _comedi_close(comedi_t *it)
87 {
88         subdevice *s;
89         int i;
90
91         it->magic=0;
92
93         for(i=0;i<it->n_subdevices;i++){
94                 s=it->subdevices+i;
95                 if(s->type==COMEDI_SUBD_UNUSED)
96                         continue;
97
98                 if(s->subd_flags&SDF_FLAGS){
99                         free(s->flags_list);
100                 }
101                 if(s->subd_flags&SDF_MAXDATA){
102                         free(s->maxdata_list);
103                 }
104                 if(s->subd_flags&SDF_RANGETYPE){
105                         free(s->range_type_list);
106                         free(s->rangeinfo_list);
107                 }else{
108                         free(s->rangeinfo);
109                 }
110                 if(s->cmd_mask)free(s->cmd_mask);
111                 if(s->cmd_timed)free(s->cmd_timed);
112         }
113         if(it->subdevices){
114                 free(it->subdevices);
115         }
116         close(it->fd);
117         free(it);
118         return 0;
119 }
120
121 EXPORT_ALIAS_DEFAULT(_comedi_cancel,comedi_cancel,0.7.18);
122 int _comedi_cancel(comedi_t *it,unsigned int subdevice)
123 {
124         return comedi_ioctl(it->fd,COMEDI_CANCEL,subdevice);
125 }
126
127 EXPORT_ALIAS_DEFAULT(_comedi_poll,comedi_poll,0.7.18);
128 int _comedi_poll(comedi_t *it,unsigned int subdevice)
129 {
130         return comedi_ioctl(it->fd,COMEDI_POLL,subdevice);
131 }
132
133 EXPORT_ALIAS_DEFAULT(_comedi_fileno,comedi_fileno,0.7.18);
134 int _comedi_fileno(comedi_t *it)
135 {
136         if(!it)
137                 return -1;
138
139         return it->fd;
140 }
141
142 EXPORT_ALIAS_DEFAULT(_comedi_trigger,comedi_trigger,0.7.18);
143 int _comedi_trigger(comedi_t *it,comedi_trig *t)
144 {
145         if(!it || !t)
146                 return -1;
147
148         return comedi_ioctl(it->fd, COMEDI_TRIG, (unsigned long)t);
149 }
150
151 EXPORT_ALIAS_DEFAULT(_comedi_command,comedi_command,0.7.18);
152 int _comedi_command(comedi_t *it,comedi_cmd *t)
153 {
154         int ret;
155         ret = comedi_ioctl(it->fd, COMEDI_CMD, (unsigned long)t);
156         __comedi_errno = errno;
157         switch(__comedi_errno){
158         case EIO:
159                 __comedi_errno = ECMDNOTSUPP;
160                 break;
161         }
162         return ret;
163 }
164
165 EXPORT_ALIAS_DEFAULT(_comedi_command_test,comedi_command_test,0.7.18);
166 int _comedi_command_test(comedi_t *it,comedi_cmd *t)
167 {
168         int ret;
169         ret = comedi_ioctl(it->fd, COMEDI_CMDTEST, (unsigned long)t);
170         __comedi_errno = errno;
171         switch(__comedi_errno){
172         case EIO:
173                 __comedi_errno = ECMDNOTSUPP;
174                 break;
175         }
176         return ret;
177 }
178
179 EXPORT_ALIAS_DEFAULT(_comedi_do_insnlist,comedi_do_insnlist,0.7.18);
180 int _comedi_do_insnlist(comedi_t *it,comedi_insnlist *il)
181 {
182         int ret;
183         ret = comedi_ioctl(it->fd, COMEDI_INSNLIST, (unsigned long)il);
184         __comedi_errno = errno;
185         return ret;
186 }
187
188 EXPORT_ALIAS_DEFAULT(_comedi_do_insn,comedi_do_insn,0.7.18);
189 int _comedi_do_insn(comedi_t *it,comedi_insn *insn)
190 {
191         if(it->has_insn_ioctl){
192                 return comedi_ioctl(it->fd, COMEDI_INSN, (unsigned long)insn);
193         }else{
194                 comedi_insnlist il;
195                 int ret;
196
197                 il.n_insns = 1;
198                 il.insns = insn;
199
200                 ret = comedi_ioctl(it->fd, COMEDI_INSNLIST, (unsigned long)&il);
201
202                 if(ret<0)return ret;
203                 return insn->n;
204         }
205 }
206
207 EXPORT_ALIAS_DEFAULT(_comedi_lock,comedi_lock,0.7.18);
208 int _comedi_lock(comedi_t *it,unsigned int subdevice)
209 {
210         return comedi_ioctl(it->fd, COMEDI_LOCK, subdevice);
211 }
212
213 EXPORT_ALIAS_DEFAULT(_comedi_unlock,comedi_unlock,0.7.18);
214 int _comedi_unlock(comedi_t *it,unsigned int subdevice)
215 {
216         return comedi_ioctl(it->fd, COMEDI_UNLOCK, subdevice);
217 }
218