Commit 3b6b25b5ddf4485e89432a35a7d79d371ba6eba1

Authored by Greg Kroah-Hartman
1 parent 2434358ac7

Staging: comedi: range.c: properly mark up __user pointers

This is the start of cleaning up the user pointer markings
in the comedi core.

Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Frank Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 5 changed files with 10 additions and 8 deletions Inline Diff

drivers/staging/comedi/comedi.h
1 /* 1 /*
2 include/comedi.h (installed as /usr/include/comedi.h) 2 include/comedi.h (installed as /usr/include/comedi.h)
3 header file for comedi 3 header file for comedi
4 4
5 COMEDI - Linux Control and Measurement Device Interface 5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org> 6 Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by 9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 21
22 */ 22 */
23 23
24 #ifndef _COMEDI_H 24 #ifndef _COMEDI_H
25 #define _COMEDI_H 25 #define _COMEDI_H
26 26
27 #define COMEDI_MAJORVERSION 0 27 #define COMEDI_MAJORVERSION 0
28 #define COMEDI_MINORVERSION 7 28 #define COMEDI_MINORVERSION 7
29 #define COMEDI_MICROVERSION 76 29 #define COMEDI_MICROVERSION 76
30 #define VERSION "0.7.76" 30 #define VERSION "0.7.76"
31 31
32 /* comedi's major device number */ 32 /* comedi's major device number */
33 #define COMEDI_MAJOR 98 33 #define COMEDI_MAJOR 98
34 34
35 /* 35 /*
36 maximum number of minor devices. This can be increased, although 36 maximum number of minor devices. This can be increased, although
37 kernel structures are currently statically allocated, thus you 37 kernel structures are currently statically allocated, thus you
38 don't want this to be much more than you actually use. 38 don't want this to be much more than you actually use.
39 */ 39 */
40 #define COMEDI_NDEVICES 16 40 #define COMEDI_NDEVICES 16
41 41
42 /* number of config options in the config structure */ 42 /* number of config options in the config structure */
43 #define COMEDI_NDEVCONFOPTS 32 43 #define COMEDI_NDEVCONFOPTS 32
44 /*length of nth chunk of firmware data*/ 44 /*length of nth chunk of firmware data*/
45 #define COMEDI_DEVCONF_AUX_DATA3_LENGTH 25 45 #define COMEDI_DEVCONF_AUX_DATA3_LENGTH 25
46 #define COMEDI_DEVCONF_AUX_DATA2_LENGTH 26 46 #define COMEDI_DEVCONF_AUX_DATA2_LENGTH 26
47 #define COMEDI_DEVCONF_AUX_DATA1_LENGTH 27 47 #define COMEDI_DEVCONF_AUX_DATA1_LENGTH 27
48 #define COMEDI_DEVCONF_AUX_DATA0_LENGTH 28 48 #define COMEDI_DEVCONF_AUX_DATA0_LENGTH 28
49 #define COMEDI_DEVCONF_AUX_DATA_HI 29 /* most significant 32 bits of pointer address (if needed) */ 49 #define COMEDI_DEVCONF_AUX_DATA_HI 29 /* most significant 32 bits of pointer address (if needed) */
50 #define COMEDI_DEVCONF_AUX_DATA_LO 30 /* least significant 32 bits of pointer address */ 50 #define COMEDI_DEVCONF_AUX_DATA_LO 30 /* least significant 32 bits of pointer address */
51 #define COMEDI_DEVCONF_AUX_DATA_LENGTH 31 /* total data length */ 51 #define COMEDI_DEVCONF_AUX_DATA_LENGTH 31 /* total data length */
52 52
53 /* max length of device and driver names */ 53 /* max length of device and driver names */
54 #define COMEDI_NAMELEN 20 54 #define COMEDI_NAMELEN 20
55 55
56 /* packs and unpacks a channel/range number */ 56 /* packs and unpacks a channel/range number */
57 57
58 #define CR_PACK(chan, rng, aref) ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan)) 58 #define CR_PACK(chan, rng, aref) ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan))
59 #define CR_PACK_FLAGS(chan, range, aref, flags) (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK)) 59 #define CR_PACK_FLAGS(chan, range, aref, flags) (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK))
60 60
61 #define CR_CHAN(a) ((a)&0xffff) 61 #define CR_CHAN(a) ((a)&0xffff)
62 #define CR_RANGE(a) (((a)>>16)&0xff) 62 #define CR_RANGE(a) (((a)>>16)&0xff)
63 #define CR_AREF(a) (((a)>>24)&0x03) 63 #define CR_AREF(a) (((a)>>24)&0x03)
64 64
65 #define CR_FLAGS_MASK 0xfc000000 65 #define CR_FLAGS_MASK 0xfc000000
66 #define CR_ALT_FILTER (1<<26) 66 #define CR_ALT_FILTER (1<<26)
67 #define CR_DITHER CR_ALT_FILTER 67 #define CR_DITHER CR_ALT_FILTER
68 #define CR_DEGLITCH CR_ALT_FILTER 68 #define CR_DEGLITCH CR_ALT_FILTER
69 #define CR_ALT_SOURCE (1<<27) 69 #define CR_ALT_SOURCE (1<<27)
70 #define CR_EDGE (1<<30) 70 #define CR_EDGE (1<<30)
71 #define CR_INVERT (1<<31) 71 #define CR_INVERT (1<<31)
72 72
73 #define AREF_GROUND 0x00 /* analog ref = analog ground */ 73 #define AREF_GROUND 0x00 /* analog ref = analog ground */
74 #define AREF_COMMON 0x01 /* analog ref = analog common */ 74 #define AREF_COMMON 0x01 /* analog ref = analog common */
75 #define AREF_DIFF 0x02 /* analog ref = differential */ 75 #define AREF_DIFF 0x02 /* analog ref = differential */
76 #define AREF_OTHER 0x03 /* analog ref = other (undefined) */ 76 #define AREF_OTHER 0x03 /* analog ref = other (undefined) */
77 77
78 /* counters -- these are arbitrary values */ 78 /* counters -- these are arbitrary values */
79 #define GPCT_RESET 0x0001 79 #define GPCT_RESET 0x0001
80 #define GPCT_SET_SOURCE 0x0002 80 #define GPCT_SET_SOURCE 0x0002
81 #define GPCT_SET_GATE 0x0004 81 #define GPCT_SET_GATE 0x0004
82 #define GPCT_SET_DIRECTION 0x0008 82 #define GPCT_SET_DIRECTION 0x0008
83 #define GPCT_SET_OPERATION 0x0010 83 #define GPCT_SET_OPERATION 0x0010
84 #define GPCT_ARM 0x0020 84 #define GPCT_ARM 0x0020
85 #define GPCT_DISARM 0x0040 85 #define GPCT_DISARM 0x0040
86 #define GPCT_GET_INT_CLK_FRQ 0x0080 86 #define GPCT_GET_INT_CLK_FRQ 0x0080
87 87
88 #define GPCT_INT_CLOCK 0x0001 88 #define GPCT_INT_CLOCK 0x0001
89 #define GPCT_EXT_PIN 0x0002 89 #define GPCT_EXT_PIN 0x0002
90 #define GPCT_NO_GATE 0x0004 90 #define GPCT_NO_GATE 0x0004
91 #define GPCT_UP 0x0008 91 #define GPCT_UP 0x0008
92 #define GPCT_DOWN 0x0010 92 #define GPCT_DOWN 0x0010
93 #define GPCT_HWUD 0x0020 93 #define GPCT_HWUD 0x0020
94 #define GPCT_SIMPLE_EVENT 0x0040 94 #define GPCT_SIMPLE_EVENT 0x0040
95 #define GPCT_SINGLE_PERIOD 0x0080 95 #define GPCT_SINGLE_PERIOD 0x0080
96 #define GPCT_SINGLE_PW 0x0100 96 #define GPCT_SINGLE_PW 0x0100
97 #define GPCT_CONT_PULSE_OUT 0x0200 97 #define GPCT_CONT_PULSE_OUT 0x0200
98 #define GPCT_SINGLE_PULSE_OUT 0x0400 98 #define GPCT_SINGLE_PULSE_OUT 0x0400
99 99
100 /* instructions */ 100 /* instructions */
101 101
102 #define INSN_MASK_WRITE 0x8000000 102 #define INSN_MASK_WRITE 0x8000000
103 #define INSN_MASK_READ 0x4000000 103 #define INSN_MASK_READ 0x4000000
104 #define INSN_MASK_SPECIAL 0x2000000 104 #define INSN_MASK_SPECIAL 0x2000000
105 105
106 #define INSN_READ (0 | INSN_MASK_READ) 106 #define INSN_READ (0 | INSN_MASK_READ)
107 #define INSN_WRITE (1 | INSN_MASK_WRITE) 107 #define INSN_WRITE (1 | INSN_MASK_WRITE)
108 #define INSN_BITS (2 | INSN_MASK_READ|INSN_MASK_WRITE) 108 #define INSN_BITS (2 | INSN_MASK_READ|INSN_MASK_WRITE)
109 #define INSN_CONFIG (3 | INSN_MASK_READ|INSN_MASK_WRITE) 109 #define INSN_CONFIG (3 | INSN_MASK_READ|INSN_MASK_WRITE)
110 #define INSN_GTOD (4 | INSN_MASK_READ|INSN_MASK_SPECIAL) 110 #define INSN_GTOD (4 | INSN_MASK_READ|INSN_MASK_SPECIAL)
111 #define INSN_WAIT (5 | INSN_MASK_WRITE|INSN_MASK_SPECIAL) 111 #define INSN_WAIT (5 | INSN_MASK_WRITE|INSN_MASK_SPECIAL)
112 #define INSN_INTTRIG (6 | INSN_MASK_WRITE|INSN_MASK_SPECIAL) 112 #define INSN_INTTRIG (6 | INSN_MASK_WRITE|INSN_MASK_SPECIAL)
113 113
114 /* trigger flags */ 114 /* trigger flags */
115 /* These flags are used in comedi_trig structures */ 115 /* These flags are used in comedi_trig structures */
116 116
117 #define TRIG_BOGUS 0x0001 /* do the motions */ 117 #define TRIG_BOGUS 0x0001 /* do the motions */
118 #define TRIG_DITHER 0x0002 /* enable dithering */ 118 #define TRIG_DITHER 0x0002 /* enable dithering */
119 #define TRIG_DEGLITCH 0x0004 /* enable deglitching */ 119 #define TRIG_DEGLITCH 0x0004 /* enable deglitching */
120 /*#define TRIG_RT 0x0008 *//* perform op in real time */ 120 /*#define TRIG_RT 0x0008 *//* perform op in real time */
121 #define TRIG_CONFIG 0x0010 /* perform configuration, not triggering */ 121 #define TRIG_CONFIG 0x0010 /* perform configuration, not triggering */
122 #define TRIG_WAKE_EOS 0x0020 /* wake up on end-of-scan events */ 122 #define TRIG_WAKE_EOS 0x0020 /* wake up on end-of-scan events */
123 /*#define TRIG_WRITE 0x0040*//* write to bidirectional devices */ 123 /*#define TRIG_WRITE 0x0040*//* write to bidirectional devices */
124 124
125 /* command flags */ 125 /* command flags */
126 /* These flags are used in comedi_cmd structures */ 126 /* These flags are used in comedi_cmd structures */
127 127
128 #define CMDF_PRIORITY 0x00000008 /* try to use a real-time interrupt while performing command */ 128 #define CMDF_PRIORITY 0x00000008 /* try to use a real-time interrupt while performing command */
129 129
130 #define TRIG_RT CMDF_PRIORITY /* compatibility definition */ 130 #define TRIG_RT CMDF_PRIORITY /* compatibility definition */
131 131
132 #define CMDF_WRITE 0x00000040 132 #define CMDF_WRITE 0x00000040
133 #define TRIG_WRITE CMDF_WRITE /* compatibility definition */ 133 #define TRIG_WRITE CMDF_WRITE /* compatibility definition */
134 134
135 #define CMDF_RAWDATA 0x00000080 135 #define CMDF_RAWDATA 0x00000080
136 136
137 #define COMEDI_EV_START 0x00040000 137 #define COMEDI_EV_START 0x00040000
138 #define COMEDI_EV_SCAN_BEGIN 0x00080000 138 #define COMEDI_EV_SCAN_BEGIN 0x00080000
139 #define COMEDI_EV_CONVERT 0x00100000 139 #define COMEDI_EV_CONVERT 0x00100000
140 #define COMEDI_EV_SCAN_END 0x00200000 140 #define COMEDI_EV_SCAN_END 0x00200000
141 #define COMEDI_EV_STOP 0x00400000 141 #define COMEDI_EV_STOP 0x00400000
142 142
143 #define TRIG_ROUND_MASK 0x00030000 143 #define TRIG_ROUND_MASK 0x00030000
144 #define TRIG_ROUND_NEAREST 0x00000000 144 #define TRIG_ROUND_NEAREST 0x00000000
145 #define TRIG_ROUND_DOWN 0x00010000 145 #define TRIG_ROUND_DOWN 0x00010000
146 #define TRIG_ROUND_UP 0x00020000 146 #define TRIG_ROUND_UP 0x00020000
147 #define TRIG_ROUND_UP_NEXT 0x00030000 147 #define TRIG_ROUND_UP_NEXT 0x00030000
148 148
149 /* trigger sources */ 149 /* trigger sources */
150 150
151 #define TRIG_ANY 0xffffffff 151 #define TRIG_ANY 0xffffffff
152 #define TRIG_INVALID 0x00000000 152 #define TRIG_INVALID 0x00000000
153 153
154 #define TRIG_NONE 0x00000001 /* never trigger */ 154 #define TRIG_NONE 0x00000001 /* never trigger */
155 #define TRIG_NOW 0x00000002 /* trigger now + N ns */ 155 #define TRIG_NOW 0x00000002 /* trigger now + N ns */
156 #define TRIG_FOLLOW 0x00000004 /* trigger on next lower level trig */ 156 #define TRIG_FOLLOW 0x00000004 /* trigger on next lower level trig */
157 #define TRIG_TIME 0x00000008 /* trigger at time N ns */ 157 #define TRIG_TIME 0x00000008 /* trigger at time N ns */
158 #define TRIG_TIMER 0x00000010 /* trigger at rate N ns */ 158 #define TRIG_TIMER 0x00000010 /* trigger at rate N ns */
159 #define TRIG_COUNT 0x00000020 /* trigger when count reaches N */ 159 #define TRIG_COUNT 0x00000020 /* trigger when count reaches N */
160 #define TRIG_EXT 0x00000040 /* trigger on external signal N */ 160 #define TRIG_EXT 0x00000040 /* trigger on external signal N */
161 #define TRIG_INT 0x00000080 /* trigger on comedi-internal signal N */ 161 #define TRIG_INT 0x00000080 /* trigger on comedi-internal signal N */
162 #define TRIG_OTHER 0x00000100 /* driver defined */ 162 #define TRIG_OTHER 0x00000100 /* driver defined */
163 163
164 /* subdevice flags */ 164 /* subdevice flags */
165 165
166 #define SDF_BUSY 0x0001 /* device is busy */ 166 #define SDF_BUSY 0x0001 /* device is busy */
167 #define SDF_BUSY_OWNER 0x0002 /* device is busy with your job */ 167 #define SDF_BUSY_OWNER 0x0002 /* device is busy with your job */
168 #define SDF_LOCKED 0x0004 /* subdevice is locked */ 168 #define SDF_LOCKED 0x0004 /* subdevice is locked */
169 #define SDF_LOCK_OWNER 0x0008 /* you own lock */ 169 #define SDF_LOCK_OWNER 0x0008 /* you own lock */
170 #define SDF_MAXDATA 0x0010 /* maxdata depends on channel */ 170 #define SDF_MAXDATA 0x0010 /* maxdata depends on channel */
171 #define SDF_FLAGS 0x0020 /* flags depend on channel */ 171 #define SDF_FLAGS 0x0020 /* flags depend on channel */
172 #define SDF_RANGETYPE 0x0040 /* range type depends on channel */ 172 #define SDF_RANGETYPE 0x0040 /* range type depends on channel */
173 #define SDF_MODE0 0x0080 /* can do mode 0 */ 173 #define SDF_MODE0 0x0080 /* can do mode 0 */
174 #define SDF_MODE1 0x0100 /* can do mode 1 */ 174 #define SDF_MODE1 0x0100 /* can do mode 1 */
175 #define SDF_MODE2 0x0200 /* can do mode 2 */ 175 #define SDF_MODE2 0x0200 /* can do mode 2 */
176 #define SDF_MODE3 0x0400 /* can do mode 3 */ 176 #define SDF_MODE3 0x0400 /* can do mode 3 */
177 #define SDF_MODE4 0x0800 /* can do mode 4 */ 177 #define SDF_MODE4 0x0800 /* can do mode 4 */
178 #define SDF_CMD 0x1000 /* can do commands (deprecated) */ 178 #define SDF_CMD 0x1000 /* can do commands (deprecated) */
179 #define SDF_SOFT_CALIBRATED 0x2000 /* subdevice uses software calibration */ 179 #define SDF_SOFT_CALIBRATED 0x2000 /* subdevice uses software calibration */
180 #define SDF_CMD_WRITE 0x4000 /* can do output commands */ 180 #define SDF_CMD_WRITE 0x4000 /* can do output commands */
181 #define SDF_CMD_READ 0x8000 /* can do input commands */ 181 #define SDF_CMD_READ 0x8000 /* can do input commands */
182 182
183 #define SDF_READABLE 0x00010000 /* subdevice can be read (e.g. analog input) */ 183 #define SDF_READABLE 0x00010000 /* subdevice can be read (e.g. analog input) */
184 #define SDF_WRITABLE 0x00020000 /* subdevice can be written (e.g. analog output) */ 184 #define SDF_WRITABLE 0x00020000 /* subdevice can be written (e.g. analog output) */
185 #define SDF_WRITEABLE SDF_WRITABLE /* spelling error in API */ 185 #define SDF_WRITEABLE SDF_WRITABLE /* spelling error in API */
186 #define SDF_INTERNAL 0x00040000 /* subdevice does not have externally visible lines */ 186 #define SDF_INTERNAL 0x00040000 /* subdevice does not have externally visible lines */
187 #define SDF_GROUND 0x00100000 /* can do aref=ground */ 187 #define SDF_GROUND 0x00100000 /* can do aref=ground */
188 #define SDF_COMMON 0x00200000 /* can do aref=common */ 188 #define SDF_COMMON 0x00200000 /* can do aref=common */
189 #define SDF_DIFF 0x00400000 /* can do aref=diff */ 189 #define SDF_DIFF 0x00400000 /* can do aref=diff */
190 #define SDF_OTHER 0x00800000 /* can do aref=other */ 190 #define SDF_OTHER 0x00800000 /* can do aref=other */
191 #define SDF_DITHER 0x01000000 /* can do dithering */ 191 #define SDF_DITHER 0x01000000 /* can do dithering */
192 #define SDF_DEGLITCH 0x02000000 /* can do deglitching */ 192 #define SDF_DEGLITCH 0x02000000 /* can do deglitching */
193 #define SDF_MMAP 0x04000000 /* can do mmap() */ 193 #define SDF_MMAP 0x04000000 /* can do mmap() */
194 #define SDF_RUNNING 0x08000000 /* subdevice is acquiring data */ 194 #define SDF_RUNNING 0x08000000 /* subdevice is acquiring data */
195 #define SDF_LSAMPL 0x10000000 /* subdevice uses 32-bit samples */ 195 #define SDF_LSAMPL 0x10000000 /* subdevice uses 32-bit samples */
196 #define SDF_PACKED 0x20000000 /* subdevice can do packed DIO */ 196 #define SDF_PACKED 0x20000000 /* subdevice can do packed DIO */
197 /* re recyle these flags for PWM */ 197 /* re recyle these flags for PWM */
198 #define SDF_PWM_COUNTER SDF_MODE0 /* PWM can automatically switch off */ 198 #define SDF_PWM_COUNTER SDF_MODE0 /* PWM can automatically switch off */
199 #define SDF_PWM_HBRIDGE SDF_MODE1 /* PWM is signed (H-bridge) */ 199 #define SDF_PWM_HBRIDGE SDF_MODE1 /* PWM is signed (H-bridge) */
200 200
201 /* subdevice types */ 201 /* subdevice types */
202 202
203 enum comedi_subdevice_type { 203 enum comedi_subdevice_type {
204 COMEDI_SUBD_UNUSED, /* unused by driver */ 204 COMEDI_SUBD_UNUSED, /* unused by driver */
205 COMEDI_SUBD_AI, /* analog input */ 205 COMEDI_SUBD_AI, /* analog input */
206 COMEDI_SUBD_AO, /* analog output */ 206 COMEDI_SUBD_AO, /* analog output */
207 COMEDI_SUBD_DI, /* digital input */ 207 COMEDI_SUBD_DI, /* digital input */
208 COMEDI_SUBD_DO, /* digital output */ 208 COMEDI_SUBD_DO, /* digital output */
209 COMEDI_SUBD_DIO, /* digital input/output */ 209 COMEDI_SUBD_DIO, /* digital input/output */
210 COMEDI_SUBD_COUNTER, /* counter */ 210 COMEDI_SUBD_COUNTER, /* counter */
211 COMEDI_SUBD_TIMER, /* timer */ 211 COMEDI_SUBD_TIMER, /* timer */
212 COMEDI_SUBD_MEMORY, /* memory, EEPROM, DPRAM */ 212 COMEDI_SUBD_MEMORY, /* memory, EEPROM, DPRAM */
213 COMEDI_SUBD_CALIB, /* calibration DACs */ 213 COMEDI_SUBD_CALIB, /* calibration DACs */
214 COMEDI_SUBD_PROC, /* processor, DSP */ 214 COMEDI_SUBD_PROC, /* processor, DSP */
215 COMEDI_SUBD_SERIAL, /* serial IO */ 215 COMEDI_SUBD_SERIAL, /* serial IO */
216 COMEDI_SUBD_PWM /* PWM */ 216 COMEDI_SUBD_PWM /* PWM */
217 }; 217 };
218 218
219 /* configuration instructions */ 219 /* configuration instructions */
220 220
221 enum configuration_ids { 221 enum configuration_ids {
222 INSN_CONFIG_DIO_INPUT = 0, 222 INSN_CONFIG_DIO_INPUT = 0,
223 INSN_CONFIG_DIO_OUTPUT = 1, 223 INSN_CONFIG_DIO_OUTPUT = 1,
224 INSN_CONFIG_DIO_OPENDRAIN = 2, 224 INSN_CONFIG_DIO_OPENDRAIN = 2,
225 INSN_CONFIG_ANALOG_TRIG = 16, 225 INSN_CONFIG_ANALOG_TRIG = 16,
226 /* INSN_CONFIG_WAVEFORM = 17, */ 226 /* INSN_CONFIG_WAVEFORM = 17, */
227 /* INSN_CONFIG_TRIG = 18, */ 227 /* INSN_CONFIG_TRIG = 18, */
228 /* INSN_CONFIG_COUNTER = 19, */ 228 /* INSN_CONFIG_COUNTER = 19, */
229 INSN_CONFIG_ALT_SOURCE = 20, 229 INSN_CONFIG_ALT_SOURCE = 20,
230 INSN_CONFIG_DIGITAL_TRIG = 21, 230 INSN_CONFIG_DIGITAL_TRIG = 21,
231 INSN_CONFIG_BLOCK_SIZE = 22, 231 INSN_CONFIG_BLOCK_SIZE = 22,
232 INSN_CONFIG_TIMER_1 = 23, 232 INSN_CONFIG_TIMER_1 = 23,
233 INSN_CONFIG_FILTER = 24, 233 INSN_CONFIG_FILTER = 24,
234 INSN_CONFIG_CHANGE_NOTIFY = 25, 234 INSN_CONFIG_CHANGE_NOTIFY = 25,
235 235
236 /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26, 236 /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26,
237 INSN_CONFIG_BIDIRECTIONAL_DATA = 27, 237 INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
238 INSN_CONFIG_DIO_QUERY = 28, 238 INSN_CONFIG_DIO_QUERY = 28,
239 INSN_CONFIG_PWM_OUTPUT = 29, 239 INSN_CONFIG_PWM_OUTPUT = 29,
240 INSN_CONFIG_GET_PWM_OUTPUT = 30, 240 INSN_CONFIG_GET_PWM_OUTPUT = 30,
241 INSN_CONFIG_ARM = 31, 241 INSN_CONFIG_ARM = 31,
242 INSN_CONFIG_DISARM = 32, 242 INSN_CONFIG_DISARM = 32,
243 INSN_CONFIG_GET_COUNTER_STATUS = 33, 243 INSN_CONFIG_GET_COUNTER_STATUS = 33,
244 INSN_CONFIG_RESET = 34, 244 INSN_CONFIG_RESET = 34,
245 INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001, /* Use CTR as single pulsegenerator */ 245 INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001, /* Use CTR as single pulsegenerator */
246 INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002, /* Use CTR as pulsetraingenerator */ 246 INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002, /* Use CTR as pulsetraingenerator */
247 INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, /* Use the counter as encoder */ 247 INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, /* Use the counter as encoder */
248 INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */ 248 INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */
249 INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */ 249 INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */
250 INSN_CONFIG_SET_CLOCK_SRC = 2003, /* Set master clock source */ 250 INSN_CONFIG_SET_CLOCK_SRC = 2003, /* Set master clock source */
251 INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */ 251 INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
252 INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ 252 INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
253 /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ 253 /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */
254 INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of 254 INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of
255 subdevice's on-board 255 subdevice's on-board
256 fifos used during 256 fifos used during
257 streaming 257 streaming
258 input/output */ 258 input/output */
259 INSN_CONFIG_SET_COUNTER_MODE = 4097, 259 INSN_CONFIG_SET_COUNTER_MODE = 4097,
260 INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */ 260 INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */
261 INSN_CONFIG_8254_READ_STATUS = 4098, 261 INSN_CONFIG_8254_READ_STATUS = 4098,
262 INSN_CONFIG_SET_ROUTING = 4099, 262 INSN_CONFIG_SET_ROUTING = 4099,
263 INSN_CONFIG_GET_ROUTING = 4109, 263 INSN_CONFIG_GET_ROUTING = 4109,
264 /* PWM */ 264 /* PWM */
265 INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */ 265 INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */
266 INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */ 266 INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */
267 INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */ 267 INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */
268 INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, /* sets H bridge: duty cycle and sign bit for a relay at the same time */ 268 INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, /* sets H bridge: duty cycle and sign bit for a relay at the same time */
269 INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 /* gets H bridge data: duty cycle and the sign bit */ 269 INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 /* gets H bridge data: duty cycle and the sign bit */
270 }; 270 };
271 271
272 enum comedi_io_direction { 272 enum comedi_io_direction {
273 COMEDI_INPUT = 0, 273 COMEDI_INPUT = 0,
274 COMEDI_OUTPUT = 1, 274 COMEDI_OUTPUT = 1,
275 COMEDI_OPENDRAIN = 2 275 COMEDI_OPENDRAIN = 2
276 }; 276 };
277 277
278 enum comedi_support_level { 278 enum comedi_support_level {
279 COMEDI_UNKNOWN_SUPPORT = 0, 279 COMEDI_UNKNOWN_SUPPORT = 0,
280 COMEDI_SUPPORTED, 280 COMEDI_SUPPORTED,
281 COMEDI_UNSUPPORTED 281 COMEDI_UNSUPPORTED
282 }; 282 };
283 283
284 /* ioctls */ 284 /* ioctls */
285 285
286 #define CIO 'd' 286 #define CIO 'd'
287 #define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig) 287 #define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
288 #define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo) 288 #define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
289 #define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo) 289 #define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
290 #define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo) 290 #define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
291 #define COMEDI_TRIG _IOWR(CIO, 4, comedi_trig) 291 #define COMEDI_TRIG _IOWR(CIO, 4, comedi_trig)
292 #define COMEDI_LOCK _IO(CIO, 5) 292 #define COMEDI_LOCK _IO(CIO, 5)
293 #define COMEDI_UNLOCK _IO(CIO, 6) 293 #define COMEDI_UNLOCK _IO(CIO, 6)
294 #define COMEDI_CANCEL _IO(CIO, 7) 294 #define COMEDI_CANCEL _IO(CIO, 7)
295 #define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo) 295 #define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
296 #define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd) 296 #define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
297 #define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd) 297 #define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
298 #define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist) 298 #define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
299 #define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn) 299 #define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
300 #define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig) 300 #define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
301 #define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo) 301 #define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
302 #define COMEDI_POLL _IO(CIO, 15) 302 #define COMEDI_POLL _IO(CIO, 15)
303 303
304 /* structures */ 304 /* structures */
305 305
306 struct comedi_trig { 306 struct comedi_trig {
307 unsigned int subdev; /* subdevice */ 307 unsigned int subdev; /* subdevice */
308 unsigned int mode; /* mode */ 308 unsigned int mode; /* mode */
309 unsigned int flags; 309 unsigned int flags;
310 unsigned int n_chan; /* number of channels */ 310 unsigned int n_chan; /* number of channels */
311 unsigned int *chanlist; /* channel/range list */ 311 unsigned int *chanlist; /* channel/range list */
312 short *data; /* data list, size depends on subd flags */ 312 short *data; /* data list, size depends on subd flags */
313 unsigned int n; /* number of scans */ 313 unsigned int n; /* number of scans */
314 unsigned int trigsrc; 314 unsigned int trigsrc;
315 unsigned int trigvar; 315 unsigned int trigvar;
316 unsigned int trigvar1; 316 unsigned int trigvar1;
317 unsigned int data_len; 317 unsigned int data_len;
318 unsigned int unused[3]; 318 unsigned int unused[3];
319 }; 319 };
320 320
321 struct comedi_insn { 321 struct comedi_insn {
322 unsigned int insn; 322 unsigned int insn;
323 unsigned int n; 323 unsigned int n;
324 unsigned int *data; 324 unsigned int *data;
325 unsigned int subdev; 325 unsigned int subdev;
326 unsigned int chanspec; 326 unsigned int chanspec;
327 unsigned int unused[3]; 327 unsigned int unused[3];
328 }; 328 };
329 329
330 struct comedi_insnlist { 330 struct comedi_insnlist {
331 unsigned int n_insns; 331 unsigned int n_insns;
332 struct comedi_insn *insns; 332 struct comedi_insn *insns;
333 }; 333 };
334 334
335 struct comedi_cmd { 335 struct comedi_cmd {
336 unsigned int subdev; 336 unsigned int subdev;
337 unsigned int flags; 337 unsigned int flags;
338 338
339 unsigned int start_src; 339 unsigned int start_src;
340 unsigned int start_arg; 340 unsigned int start_arg;
341 341
342 unsigned int scan_begin_src; 342 unsigned int scan_begin_src;
343 unsigned int scan_begin_arg; 343 unsigned int scan_begin_arg;
344 344
345 unsigned int convert_src; 345 unsigned int convert_src;
346 unsigned int convert_arg; 346 unsigned int convert_arg;
347 347
348 unsigned int scan_end_src; 348 unsigned int scan_end_src;
349 unsigned int scan_end_arg; 349 unsigned int scan_end_arg;
350 350
351 unsigned int stop_src; 351 unsigned int stop_src;
352 unsigned int stop_arg; 352 unsigned int stop_arg;
353 353
354 unsigned int *chanlist; /* channel/range list */ 354 unsigned int *chanlist; /* channel/range list */
355 unsigned int chanlist_len; 355 unsigned int chanlist_len;
356 356
357 short *data; /* data list, size depends on subd flags */ 357 short *data; /* data list, size depends on subd flags */
358 unsigned int data_len; 358 unsigned int data_len;
359 }; 359 };
360 360
361 struct comedi_chaninfo { 361 struct comedi_chaninfo {
362 unsigned int subdev; 362 unsigned int subdev;
363 unsigned int *maxdata_list; 363 unsigned int *maxdata_list;
364 unsigned int *flaglist; 364 unsigned int *flaglist;
365 unsigned int *rangelist; 365 unsigned int *rangelist;
366 unsigned int unused[4]; 366 unsigned int unused[4];
367 }; 367 };
368 368
369 struct comedi_rangeinfo { 369 struct comedi_rangeinfo {
370 unsigned int range_type; 370 unsigned int range_type;
371 void *range_ptr; 371 void __user *range_ptr;
372 }; 372 };
373 373
374 struct comedi_krange { 374 struct comedi_krange {
375 int min; /* fixed point, multiply by 1e-6 */ 375 int min; /* fixed point, multiply by 1e-6 */
376 int max; /* fixed point, multiply by 1e-6 */ 376 int max; /* fixed point, multiply by 1e-6 */
377 unsigned int flags; 377 unsigned int flags;
378 }; 378 };
379 379
380 struct comedi_subdinfo { 380 struct comedi_subdinfo {
381 unsigned int type; 381 unsigned int type;
382 unsigned int n_chan; 382 unsigned int n_chan;
383 unsigned int subd_flags; 383 unsigned int subd_flags;
384 unsigned int timer_type; 384 unsigned int timer_type;
385 unsigned int len_chanlist; 385 unsigned int len_chanlist;
386 unsigned int maxdata; 386 unsigned int maxdata;
387 unsigned int flags; /* channel flags */ 387 unsigned int flags; /* channel flags */
388 unsigned int range_type; /* lookup in kernel */ 388 unsigned int range_type; /* lookup in kernel */
389 unsigned int settling_time_0; 389 unsigned int settling_time_0;
390 unsigned insn_bits_support; /* see support_level enum for values */ 390 unsigned insn_bits_support; /* see support_level enum for values */
391 unsigned int unused[8]; 391 unsigned int unused[8];
392 }; 392 };
393 393
394 struct comedi_devinfo { 394 struct comedi_devinfo {
395 unsigned int version_code; 395 unsigned int version_code;
396 unsigned int n_subdevs; 396 unsigned int n_subdevs;
397 char driver_name[COMEDI_NAMELEN]; 397 char driver_name[COMEDI_NAMELEN];
398 char board_name[COMEDI_NAMELEN]; 398 char board_name[COMEDI_NAMELEN];
399 int read_subdevice; 399 int read_subdevice;
400 int write_subdevice; 400 int write_subdevice;
401 int unused[30]; 401 int unused[30];
402 }; 402 };
403 403
404 struct comedi_devconfig { 404 struct comedi_devconfig {
405 char board_name[COMEDI_NAMELEN]; 405 char board_name[COMEDI_NAMELEN];
406 int options[COMEDI_NDEVCONFOPTS]; 406 int options[COMEDI_NDEVCONFOPTS];
407 }; 407 };
408 408
409 struct comedi_bufconfig { 409 struct comedi_bufconfig {
410 unsigned int subdevice; 410 unsigned int subdevice;
411 unsigned int flags; 411 unsigned int flags;
412 412
413 unsigned int maximum_size; 413 unsigned int maximum_size;
414 unsigned int size; 414 unsigned int size;
415 415
416 unsigned int unused[4]; 416 unsigned int unused[4];
417 }; 417 };
418 418
419 struct comedi_bufinfo { 419 struct comedi_bufinfo {
420 unsigned int subdevice; 420 unsigned int subdevice;
421 unsigned int bytes_read; 421 unsigned int bytes_read;
422 422
423 unsigned int buf_write_ptr; 423 unsigned int buf_write_ptr;
424 unsigned int buf_read_ptr; 424 unsigned int buf_read_ptr;
425 unsigned int buf_write_count; 425 unsigned int buf_write_count;
426 unsigned int buf_read_count; 426 unsigned int buf_read_count;
427 427
428 unsigned int bytes_written; 428 unsigned int bytes_written;
429 429
430 unsigned int unused[4]; 430 unsigned int unused[4];
431 }; 431 };
432 432
433 /* range stuff */ 433 /* range stuff */
434 434
435 #define __RANGE(a, b) ((((a)&0xffff)<<16)|((b)&0xffff)) 435 #define __RANGE(a, b) ((((a)&0xffff)<<16)|((b)&0xffff))
436 436
437 #define RANGE_OFFSET(a) (((a)>>16)&0xffff) 437 #define RANGE_OFFSET(a) (((a)>>16)&0xffff)
438 #define RANGE_LENGTH(b) ((b)&0xffff) 438 #define RANGE_LENGTH(b) ((b)&0xffff)
439 439
440 #define RF_UNIT(flags) ((flags)&0xff) 440 #define RF_UNIT(flags) ((flags)&0xff)
441 #define RF_EXTERNAL (1<<8) 441 #define RF_EXTERNAL (1<<8)
442 442
443 #define UNIT_volt 0 443 #define UNIT_volt 0
444 #define UNIT_mA 1 444 #define UNIT_mA 1
445 #define UNIT_none 2 445 #define UNIT_none 2
446 446
447 #define COMEDI_MIN_SPEED ((unsigned int)0xffffffff) 447 #define COMEDI_MIN_SPEED ((unsigned int)0xffffffff)
448 448
449 /* callback stuff */ 449 /* callback stuff */
450 /* only relevant to kernel modules. */ 450 /* only relevant to kernel modules. */
451 451
452 #define COMEDI_CB_EOS 1 /* end of scan */ 452 #define COMEDI_CB_EOS 1 /* end of scan */
453 #define COMEDI_CB_EOA 2 /* end of acquisition */ 453 #define COMEDI_CB_EOA 2 /* end of acquisition */
454 #define COMEDI_CB_BLOCK 4 /* data has arrived: wakes up read() / write() */ 454 #define COMEDI_CB_BLOCK 4 /* data has arrived: wakes up read() / write() */
455 #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ 455 #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */
456 #define COMEDI_CB_ERROR 16 /* card error during acquisition */ 456 #define COMEDI_CB_ERROR 16 /* card error during acquisition */
457 #define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ 457 #define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */
458 458
459 /**********************************************************/ 459 /**********************************************************/
460 /* everything after this line is ALPHA */ 460 /* everything after this line is ALPHA */
461 /**********************************************************/ 461 /**********************************************************/
462 462
463 /* 463 /*
464 8254 specific configuration. 464 8254 specific configuration.
465 465
466 It supports two config commands: 466 It supports two config commands:
467 467
468 0 ID: INSN_CONFIG_SET_COUNTER_MODE 468 0 ID: INSN_CONFIG_SET_COUNTER_MODE
469 1 8254 Mode 469 1 8254 Mode
470 I8254_MODE0, I8254_MODE1, ..., I8254_MODE5 470 I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
471 OR'ed with: 471 OR'ed with:
472 I8254_BCD, I8254_BINARY 472 I8254_BCD, I8254_BINARY
473 473
474 0 ID: INSN_CONFIG_8254_READ_STATUS 474 0 ID: INSN_CONFIG_8254_READ_STATUS
475 1 <-- Status byte returned here. 475 1 <-- Status byte returned here.
476 B7 = Output 476 B7 = Output
477 B6 = NULL Count 477 B6 = NULL Count
478 B5 - B0 Current mode. 478 B5 - B0 Current mode.
479 479
480 */ 480 */
481 481
482 enum i8254_mode { 482 enum i8254_mode {
483 I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */ 483 I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */
484 I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */ 484 I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */
485 I8254_MODE2 = (2 << 1), /* Rate generator */ 485 I8254_MODE2 = (2 << 1), /* Rate generator */
486 I8254_MODE3 = (3 << 1), /* Square wave mode */ 486 I8254_MODE3 = (3 << 1), /* Square wave mode */
487 I8254_MODE4 = (4 << 1), /* Software triggered strobe */ 487 I8254_MODE4 = (4 << 1), /* Software triggered strobe */
488 I8254_MODE5 = (5 << 1), /* Hardware triggered strobe (retriggerable) */ 488 I8254_MODE5 = (5 << 1), /* Hardware triggered strobe (retriggerable) */
489 I8254_BCD = 1, /* use binary-coded decimal instead of binary (pretty useless) */ 489 I8254_BCD = 1, /* use binary-coded decimal instead of binary (pretty useless) */
490 I8254_BINARY = 0 490 I8254_BINARY = 0
491 }; 491 };
492 492
493 static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel) 493 static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)
494 { 494 {
495 if (pfi_channel < 10) 495 if (pfi_channel < 10)
496 return 0x1 + pfi_channel; 496 return 0x1 + pfi_channel;
497 else 497 else
498 return 0xb + pfi_channel; 498 return 0xb + pfi_channel;
499 } static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) { 499 } static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) {
500 if (rtsi_channel < 7) 500 if (rtsi_channel < 7)
501 return 0xb + rtsi_channel; 501 return 0xb + rtsi_channel;
502 else 502 else
503 return 0x1b; 503 return 0x1b;
504 } 504 }
505 /* mode bits for NI general-purpose counters, set with 505 /* mode bits for NI general-purpose counters, set with
506 * INSN_CONFIG_SET_COUNTER_MODE */ 506 * INSN_CONFIG_SET_COUNTER_MODE */
507 #define NI_GPCT_COUNTING_MODE_SHIFT 16 507 #define NI_GPCT_COUNTING_MODE_SHIFT 16
508 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20 508 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20
509 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24 509 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
510 enum ni_gpct_mode_bits { 510 enum ni_gpct_mode_bits {
511 NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4, 511 NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
512 NI_GPCT_EDGE_GATE_MODE_MASK = 0x18, 512 NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
513 NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0, 513 NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
514 NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8, 514 NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
515 NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10, 515 NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
516 NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18, 516 NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
517 NI_GPCT_STOP_MODE_MASK = 0x60, 517 NI_GPCT_STOP_MODE_MASK = 0x60,
518 NI_GPCT_STOP_ON_GATE_BITS = 0x00, 518 NI_GPCT_STOP_ON_GATE_BITS = 0x00,
519 NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20, 519 NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
520 NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40, 520 NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
521 NI_GPCT_LOAD_B_SELECT_BIT = 0x80, 521 NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
522 NI_GPCT_OUTPUT_MODE_MASK = 0x300, 522 NI_GPCT_OUTPUT_MODE_MASK = 0x300,
523 NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100, 523 NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
524 NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200, 524 NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
525 NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300, 525 NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
526 NI_GPCT_HARDWARE_DISARM_MASK = 0xc00, 526 NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
527 NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000, 527 NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
528 NI_GPCT_DISARM_AT_TC_BITS = 0x400, 528 NI_GPCT_DISARM_AT_TC_BITS = 0x400,
529 NI_GPCT_DISARM_AT_GATE_BITS = 0x800, 529 NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
530 NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00, 530 NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
531 NI_GPCT_LOADING_ON_TC_BIT = 0x1000, 531 NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
532 NI_GPCT_LOADING_ON_GATE_BIT = 0x4000, 532 NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
533 NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT, 533 NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
534 NI_GPCT_COUNTING_MODE_NORMAL_BITS = 534 NI_GPCT_COUNTING_MODE_NORMAL_BITS =
535 0x0 << NI_GPCT_COUNTING_MODE_SHIFT, 535 0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
536 NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS = 536 NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
537 0x1 << NI_GPCT_COUNTING_MODE_SHIFT, 537 0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
538 NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS = 538 NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
539 0x2 << NI_GPCT_COUNTING_MODE_SHIFT, 539 0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
540 NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS = 540 NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
541 0x3 << NI_GPCT_COUNTING_MODE_SHIFT, 541 0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
542 NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS = 542 NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
543 0x4 << NI_GPCT_COUNTING_MODE_SHIFT, 543 0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
544 NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS = 544 NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
545 0x6 << NI_GPCT_COUNTING_MODE_SHIFT, 545 0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
546 NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT, 546 NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
547 NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS = 547 NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
548 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT, 548 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
549 NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS = 549 NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
550 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT, 550 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
551 NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS = 551 NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
552 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT, 552 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
553 NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS = 553 NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
554 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT, 554 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
555 NI_GPCT_INDEX_ENABLE_BIT = 0x400000, 555 NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
556 NI_GPCT_COUNTING_DIRECTION_MASK = 556 NI_GPCT_COUNTING_DIRECTION_MASK =
557 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT, 557 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
558 NI_GPCT_COUNTING_DIRECTION_DOWN_BITS = 558 NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
559 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT, 559 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
560 NI_GPCT_COUNTING_DIRECTION_UP_BITS = 560 NI_GPCT_COUNTING_DIRECTION_UP_BITS =
561 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT, 561 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
562 NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS = 562 NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
563 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT, 563 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
564 NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS = 564 NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
565 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT, 565 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
566 NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000, 566 NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
567 NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0, 567 NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
568 NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000, 568 NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
569 NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000, 569 NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
570 NI_GPCT_OR_GATE_BIT = 0x10000000, 570 NI_GPCT_OR_GATE_BIT = 0x10000000,
571 NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000 571 NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
572 }; 572 };
573 573
574 /* Bits for setting a clock source with 574 /* Bits for setting a clock source with
575 * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */ 575 * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */
576 enum ni_gpct_clock_source_bits { 576 enum ni_gpct_clock_source_bits {
577 NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f, 577 NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
578 NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0, 578 NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
579 NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1, 579 NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
580 NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2, 580 NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
581 NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3, 581 NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
582 NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4, 582 NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
583 NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5, 583 NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
584 NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6, /* NI 660x-specific */ 584 NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6, /* NI 660x-specific */
585 NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7, 585 NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
586 NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8, 586 NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
587 NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9, 587 NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
588 NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000, 588 NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
589 NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0, 589 NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
590 NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, /* divide source by 2 */ 590 NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, /* divide source by 2 */
591 NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, /* divide source by 8 */ 591 NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, /* divide source by 8 */
592 NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000 592 NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
593 }; 593 };
594 static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) 594 static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)
595 { 595 {
596 /* NI 660x-specific */ 596 /* NI 660x-specific */
597 return 0x10 + n; 597 return 0x10 + n;
598 } 598 }
599 static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n) 599 static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)
600 { 600 {
601 return 0x18 + n; 601 return 0x18 + n;
602 } 602 }
603 static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n) 603 static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)
604 { 604 {
605 /* no pfi on NI 660x */ 605 /* no pfi on NI 660x */
606 return 0x20 + n; 606 return 0x20 + n;
607 } 607 }
608 608
609 /* Possibilities for setting a gate source with 609 /* Possibilities for setting a gate source with
610 INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters. 610 INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
611 May be bitwise-or'd with CR_EDGE or CR_INVERT. */ 611 May be bitwise-or'd with CR_EDGE or CR_INVERT. */
612 enum ni_gpct_gate_select { 612 enum ni_gpct_gate_select {
613 /* m-series gates */ 613 /* m-series gates */
614 NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0, 614 NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
615 NI_GPCT_AI_START2_GATE_SELECT = 0x12, 615 NI_GPCT_AI_START2_GATE_SELECT = 0x12,
616 NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13, 616 NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
617 NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14, 617 NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
618 NI_GPCT_AI_START1_GATE_SELECT = 0x1c, 618 NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
619 NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d, 619 NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
620 NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e, 620 NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
621 NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f, 621 NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
622 /* more gates for 660x */ 622 /* more gates for 660x */
623 NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100, 623 NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
624 NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101, 624 NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
625 /* more gates for 660x "second gate" */ 625 /* more gates for 660x "second gate" */
626 NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201, 626 NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
627 NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e, 627 NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
628 /* m-series "second gate" sources are unknown, 628 /* m-series "second gate" sources are unknown,
629 we should add them here with an offset of 0x300 when known. */ 629 we should add them here with an offset of 0x300 when known. */
630 NI_GPCT_DISABLED_GATE_SELECT = 0x8000, 630 NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
631 }; 631 };
632 static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) 632 static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)
633 { 633 {
634 return 0x102 + n; 634 return 0x102 + n;
635 } 635 }
636 static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n) 636 static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)
637 { 637 {
638 return NI_USUAL_RTSI_SELECT(n); 638 return NI_USUAL_RTSI_SELECT(n);
639 } 639 }
640 static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n) 640 static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)
641 { 641 {
642 return NI_USUAL_PFI_SELECT(n); 642 return NI_USUAL_PFI_SELECT(n);
643 } 643 }
644 static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n) 644 static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
645 { 645 {
646 return 0x202 + n; 646 return 0x202 + n;
647 } 647 }
648 648
649 /* Possibilities for setting a source with 649 /* Possibilities for setting a source with
650 INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */ 650 INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
651 enum ni_gpct_other_index { 651 enum ni_gpct_other_index {
652 NI_GPCT_SOURCE_ENCODER_A, 652 NI_GPCT_SOURCE_ENCODER_A,
653 NI_GPCT_SOURCE_ENCODER_B, 653 NI_GPCT_SOURCE_ENCODER_B,
654 NI_GPCT_SOURCE_ENCODER_Z 654 NI_GPCT_SOURCE_ENCODER_Z
655 }; 655 };
656 enum ni_gpct_other_select { 656 enum ni_gpct_other_select {
657 /* m-series gates */ 657 /* m-series gates */
658 /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */ 658 /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
659 NI_GPCT_DISABLED_OTHER_SELECT = 0x8000, 659 NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
660 }; 660 };
661 static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n) 661 static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
662 { 662 {
663 return NI_USUAL_PFI_SELECT(n); 663 return NI_USUAL_PFI_SELECT(n);
664 } 664 }
665 665
666 /* start sources for ni general-purpose counters for use with 666 /* start sources for ni general-purpose counters for use with
667 INSN_CONFIG_ARM */ 667 INSN_CONFIG_ARM */
668 enum ni_gpct_arm_source { 668 enum ni_gpct_arm_source {
669 NI_GPCT_ARM_IMMEDIATE = 0x0, 669 NI_GPCT_ARM_IMMEDIATE = 0x0,
670 NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter and 670 NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter and
671 the adjacent paired counter 671 the adjacent paired counter
672 simultaneously */ 672 simultaneously */
673 /* NI doesn't document bits for selecting hardware arm triggers. If 673 /* NI doesn't document bits for selecting hardware arm triggers. If
674 * the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least 674 * the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
675 * significant bits (3 bits for 660x or 5 bits for m-series) through to 675 * significant bits (3 bits for 660x or 5 bits for m-series) through to
676 * the hardware. This will at least allow someone to figure out what 676 * the hardware. This will at least allow someone to figure out what
677 * the bits do later. */ 677 * the bits do later. */
678 NI_GPCT_ARM_UNKNOWN = 0x1000, 678 NI_GPCT_ARM_UNKNOWN = 0x1000,
679 }; 679 };
680 680
681 /* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */ 681 /* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */
682 enum ni_gpct_filter_select { 682 enum ni_gpct_filter_select {
683 NI_GPCT_FILTER_OFF = 0x0, 683 NI_GPCT_FILTER_OFF = 0x0,
684 NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1, 684 NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
685 NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2, 685 NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
686 NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3, 686 NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
687 NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4, 687 NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
688 NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5, 688 NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
689 NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6 689 NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
690 }; 690 };
691 691
692 /* PFI digital filtering options for ni m-series for use with 692 /* PFI digital filtering options for ni m-series for use with
693 * INSN_CONFIG_FILTER. */ 693 * INSN_CONFIG_FILTER. */
694 enum ni_pfi_filter_select { 694 enum ni_pfi_filter_select {
695 NI_PFI_FILTER_OFF = 0x0, 695 NI_PFI_FILTER_OFF = 0x0,
696 NI_PFI_FILTER_125ns = 0x1, 696 NI_PFI_FILTER_125ns = 0x1,
697 NI_PFI_FILTER_6425ns = 0x2, 697 NI_PFI_FILTER_6425ns = 0x2,
698 NI_PFI_FILTER_2550us = 0x3 698 NI_PFI_FILTER_2550us = 0x3
699 }; 699 };
700 700
701 /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */ 701 /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */
702 enum ni_mio_clock_source { 702 enum ni_mio_clock_source {
703 NI_MIO_INTERNAL_CLOCK = 0, 703 NI_MIO_INTERNAL_CLOCK = 0,
704 NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use 704 NI_MIO_RTSI_CLOCK = 1, /* doesn't work for m-series, use
705 NI_MIO_PLL_RTSI_CLOCK() */ 705 NI_MIO_PLL_RTSI_CLOCK() */
706 /* the NI_MIO_PLL_* sources are m-series only */ 706 /* the NI_MIO_PLL_* sources are m-series only */
707 NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2, 707 NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
708 NI_MIO_PLL_PXI10_CLOCK = 3, 708 NI_MIO_PLL_PXI10_CLOCK = 3,
709 NI_MIO_PLL_RTSI0_CLOCK = 4 709 NI_MIO_PLL_RTSI0_CLOCK = 4
710 }; 710 };
711 static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel) 711 static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)
712 { 712 {
713 return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel; 713 return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
714 } 714 }
715 715
716 /* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING. 716 /* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
717 The numbers assigned are not arbitrary, they correspond to the bits required 717 The numbers assigned are not arbitrary, they correspond to the bits required
718 to program the board. */ 718 to program the board. */
719 enum ni_rtsi_routing { 719 enum ni_rtsi_routing {
720 NI_RTSI_OUTPUT_ADR_START1 = 0, 720 NI_RTSI_OUTPUT_ADR_START1 = 0,
721 NI_RTSI_OUTPUT_ADR_START2 = 1, 721 NI_RTSI_OUTPUT_ADR_START2 = 1,
722 NI_RTSI_OUTPUT_SCLKG = 2, 722 NI_RTSI_OUTPUT_SCLKG = 2,
723 NI_RTSI_OUTPUT_DACUPDN = 3, 723 NI_RTSI_OUTPUT_DACUPDN = 3,
724 NI_RTSI_OUTPUT_DA_START1 = 4, 724 NI_RTSI_OUTPUT_DA_START1 = 4,
725 NI_RTSI_OUTPUT_G_SRC0 = 5, 725 NI_RTSI_OUTPUT_G_SRC0 = 5,
726 NI_RTSI_OUTPUT_G_GATE0 = 6, 726 NI_RTSI_OUTPUT_G_GATE0 = 6,
727 NI_RTSI_OUTPUT_RGOUT0 = 7, 727 NI_RTSI_OUTPUT_RGOUT0 = 7,
728 NI_RTSI_OUTPUT_RTSI_BRD_0 = 8, 728 NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
729 NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI clock 729 NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI clock
730 on line 7 */ 730 on line 7 */
731 }; 731 };
732 static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) 732 static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)
733 { 733 {
734 return NI_RTSI_OUTPUT_RTSI_BRD_0 + n; 734 return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
735 } 735 }
736 736
737 /* Signals which can be routed to an NI PFI pin on an m-series board with 737 /* Signals which can be routed to an NI PFI pin on an m-series board with
738 * INSN_CONFIG_SET_ROUTING. These numbers are also returned by 738 * INSN_CONFIG_SET_ROUTING. These numbers are also returned by
739 * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing 739 * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing
740 * cannot be changed. The numbers assigned are not arbitrary, they correspond 740 * cannot be changed. The numbers assigned are not arbitrary, they correspond
741 * to the bits required to program the board. */ 741 * to the bits required to program the board. */
742 enum ni_pfi_routing { 742 enum ni_pfi_routing {
743 NI_PFI_OUTPUT_PFI_DEFAULT = 0, 743 NI_PFI_OUTPUT_PFI_DEFAULT = 0,
744 NI_PFI_OUTPUT_AI_START1 = 1, 744 NI_PFI_OUTPUT_AI_START1 = 1,
745 NI_PFI_OUTPUT_AI_START2 = 2, 745 NI_PFI_OUTPUT_AI_START2 = 2,
746 NI_PFI_OUTPUT_AI_CONVERT = 3, 746 NI_PFI_OUTPUT_AI_CONVERT = 3,
747 NI_PFI_OUTPUT_G_SRC1 = 4, 747 NI_PFI_OUTPUT_G_SRC1 = 4,
748 NI_PFI_OUTPUT_G_GATE1 = 5, 748 NI_PFI_OUTPUT_G_GATE1 = 5,
749 NI_PFI_OUTPUT_AO_UPDATE_N = 6, 749 NI_PFI_OUTPUT_AO_UPDATE_N = 6,
750 NI_PFI_OUTPUT_AO_START1 = 7, 750 NI_PFI_OUTPUT_AO_START1 = 7,
751 NI_PFI_OUTPUT_AI_START_PULSE = 8, 751 NI_PFI_OUTPUT_AI_START_PULSE = 8,
752 NI_PFI_OUTPUT_G_SRC0 = 9, 752 NI_PFI_OUTPUT_G_SRC0 = 9,
753 NI_PFI_OUTPUT_G_GATE0 = 10, 753 NI_PFI_OUTPUT_G_GATE0 = 10,
754 NI_PFI_OUTPUT_EXT_STROBE = 11, 754 NI_PFI_OUTPUT_EXT_STROBE = 11,
755 NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12, 755 NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
756 NI_PFI_OUTPUT_GOUT0 = 13, 756 NI_PFI_OUTPUT_GOUT0 = 13,
757 NI_PFI_OUTPUT_GOUT1 = 14, 757 NI_PFI_OUTPUT_GOUT1 = 14,
758 NI_PFI_OUTPUT_FREQ_OUT = 15, 758 NI_PFI_OUTPUT_FREQ_OUT = 15,
759 NI_PFI_OUTPUT_PFI_DO = 16, 759 NI_PFI_OUTPUT_PFI_DO = 16,
760 NI_PFI_OUTPUT_I_ATRIG = 17, 760 NI_PFI_OUTPUT_I_ATRIG = 17,
761 NI_PFI_OUTPUT_RTSI0 = 18, 761 NI_PFI_OUTPUT_RTSI0 = 18,
762 NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26, 762 NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
763 NI_PFI_OUTPUT_SCXI_TRIG1 = 27, 763 NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
764 NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28, 764 NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
765 NI_PFI_OUTPUT_CDI_SAMPLE = 29, 765 NI_PFI_OUTPUT_CDI_SAMPLE = 29,
766 NI_PFI_OUTPUT_CDO_UPDATE = 30 766 NI_PFI_OUTPUT_CDO_UPDATE = 30
767 }; 767 };
768 static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) 768 static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
769 { 769 {
770 return NI_PFI_OUTPUT_RTSI0 + rtsi_channel; 770 return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
771 } 771 }
772 772
773 /* Signals which can be routed to output on a NI PFI pin on a 660x board 773 /* Signals which can be routed to output on a NI PFI pin on a 660x board
774 with INSN_CONFIG_SET_ROUTING. The numbers assigned are 774 with INSN_CONFIG_SET_ROUTING. The numbers assigned are
775 not arbitrary, they correspond to the bits required 775 not arbitrary, they correspond to the bits required
776 to program the board. Lines 0 to 7 can only be set to 776 to program the board. Lines 0 to 7 can only be set to
777 NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to 777 NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to
778 NI_660X_PFI_OUTPUT_COUNTER. */ 778 NI_660X_PFI_OUTPUT_COUNTER. */
779 enum ni_660x_pfi_routing { 779 enum ni_660x_pfi_routing {
780 NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */ 780 NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */
781 NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */ 781 NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */
782 }; 782 };
783 783
784 /* NI External Trigger lines. These values are not arbitrary, but are related 784 /* NI External Trigger lines. These values are not arbitrary, but are related
785 * to the bits required to program the board (offset by 1 for historical 785 * to the bits required to program the board (offset by 1 for historical
786 * reasons). */ 786 * reasons). */
787 static inline unsigned NI_EXT_PFI(unsigned pfi_channel) 787 static inline unsigned NI_EXT_PFI(unsigned pfi_channel)
788 { 788 {
789 return NI_USUAL_PFI_SELECT(pfi_channel) - 1; 789 return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
790 } 790 }
791 static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel) 791 static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)
792 { 792 {
793 return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1; 793 return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
794 } 794 }
795 795
796 /* status bits for INSN_CONFIG_GET_COUNTER_STATUS */ 796 /* status bits for INSN_CONFIG_GET_COUNTER_STATUS */
797 enum comedi_counter_status_flags { 797 enum comedi_counter_status_flags {
798 COMEDI_COUNTER_ARMED = 0x1, 798 COMEDI_COUNTER_ARMED = 0x1,
799 COMEDI_COUNTER_COUNTING = 0x2, 799 COMEDI_COUNTER_COUNTING = 0x2,
800 COMEDI_COUNTER_TERMINAL_COUNT = 0x4, 800 COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
801 }; 801 };
802 802
803 /* Clock sources for CDIO subdevice on NI m-series boards. Used as the 803 /* Clock sources for CDIO subdevice on NI m-series boards. Used as the
804 * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd 804 * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd
805 * with CR_INVERT to change polarity. */ 805 * with CR_INVERT to change polarity. */
806 enum ni_m_series_cdio_scan_begin_src { 806 enum ni_m_series_cdio_scan_begin_src {
807 NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0, 807 NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
808 NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18, 808 NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
809 NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19, 809 NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
810 NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20, 810 NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
811 NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28, 811 NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
812 NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29, 812 NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
813 NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30, 813 NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
814 NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31, 814 NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
815 NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32, 815 NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
816 NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33 816 NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
817 }; 817 };
818 static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) 818 static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
819 { 819 {
820 return NI_USUAL_PFI_SELECT(pfi_channel); 820 return NI_USUAL_PFI_SELECT(pfi_channel);
821 } 821 }
822 static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) 822 static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
823 { 823 {
824 return NI_USUAL_RTSI_SELECT(rtsi_channel); 824 return NI_USUAL_RTSI_SELECT(rtsi_channel);
825 } 825 }
826 826
827 /* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI 827 /* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
828 * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to 828 * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to
829 * change polarity. */ 829 * change polarity. */
830 static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) 830 static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
831 { 831 {
832 return NI_USUAL_PFI_SELECT(pfi_channel); 832 return NI_USUAL_PFI_SELECT(pfi_channel);
833 } 833 }
834 static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) 834 static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
835 { 835 {
836 return NI_USUAL_RTSI_SELECT(rtsi_channel); 836 return NI_USUAL_RTSI_SELECT(rtsi_channel);
837 } 837 }
838 838
839 /* Bits for setting a clock source with 839 /* Bits for setting a clock source with
840 * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */ 840 * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */
841 enum ni_freq_out_clock_source_bits { 841 enum ni_freq_out_clock_source_bits {
842 NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */ 842 NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */
843 NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */ 843 NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */
844 }; 844 };
845 845
846 /* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for 846 /* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
847 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ 847 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
848 enum amplc_dio_clock_source { 848 enum amplc_dio_clock_source {
849 AMPLC_DIO_CLK_CLKN, /* per channel external clock 849 AMPLC_DIO_CLK_CLKN, /* per channel external clock
850 input/output pin (pin is only an 850 input/output pin (pin is only an
851 input when clock source set to this 851 input when clock source set to this
852 value, otherwise it is an output) */ 852 value, otherwise it is an output) */
853 AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */ 853 AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */
854 AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */ 854 AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */
855 AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */ 855 AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */
856 AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */ 856 AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */
857 AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */ 857 AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */
858 AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel 858 AMPLC_DIO_CLK_OUTNM1, /* output of preceding counter channel
859 (for channel 0, preceding counter 859 (for channel 0, preceding counter
860 channel is channel 2 on preceding 860 channel is channel 2 on preceding
861 counter subdevice, for first counter 861 counter subdevice, for first counter
862 subdevice, preceding counter 862 subdevice, preceding counter
863 subdevice is the last counter 863 subdevice is the last counter
864 subdevice) */ 864 subdevice) */
865 AMPLC_DIO_CLK_EXT /* per chip external input pin */ 865 AMPLC_DIO_CLK_EXT /* per chip external input pin */
866 }; 866 };
867 867
868 /* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for 868 /* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
869 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ 869 * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
870 enum amplc_dio_gate_source { 870 enum amplc_dio_gate_source {
871 AMPLC_DIO_GAT_VCC, /* internal high logic level */ 871 AMPLC_DIO_GAT_VCC, /* internal high logic level */
872 AMPLC_DIO_GAT_GND, /* internal low logic level */ 872 AMPLC_DIO_GAT_GND, /* internal low logic level */
873 AMPLC_DIO_GAT_GATN, /* per channel external gate input */ 873 AMPLC_DIO_GAT_GATN, /* per channel external gate input */
874 AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel 874 AMPLC_DIO_GAT_NOUTNM2, /* negated output of counter channel
875 minus 2 (for channels 0 or 1, 875 minus 2 (for channels 0 or 1,
876 channel minus 2 is channel 1 or 2 on 876 channel minus 2 is channel 1 or 2 on
877 the preceding counter subdevice, for 877 the preceding counter subdevice, for
878 the first counter subdevice the 878 the first counter subdevice the
879 preceding counter subdevice is the 879 preceding counter subdevice is the
880 last counter subdevice) */ 880 last counter subdevice) */
881 AMPLC_DIO_GAT_RESERVED4, 881 AMPLC_DIO_GAT_RESERVED4,
882 AMPLC_DIO_GAT_RESERVED5, 882 AMPLC_DIO_GAT_RESERVED5,
883 AMPLC_DIO_GAT_RESERVED6, 883 AMPLC_DIO_GAT_RESERVED6,
884 AMPLC_DIO_GAT_RESERVED7 884 AMPLC_DIO_GAT_RESERVED7
885 }; 885 };
886 886
887 #endif /* _COMEDI_H */ 887 #endif /* _COMEDI_H */
888 888
drivers/staging/comedi/comedi_compat32.c
1 /* 1 /*
2 comedi/comedi_compat32.c 2 comedi/comedi_compat32.c
3 32-bit ioctl compatibility for 64-bit comedi kernel module. 3 32-bit ioctl compatibility for 64-bit comedi kernel module.
4 4
5 Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk> 5 Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
6 Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/> 6 Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
7 7
8 COMEDI - Linux Control and Measurement Device Interface 8 COMEDI - Linux Control and Measurement Device Interface
9 Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org> 9 Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version. 14 (at your option) any later version.
15 15
16 This program is distributed in the hope that it will be useful, 16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 24
25 */ 25 */
26 26
27 #define __NO_VERSION__ 27 #define __NO_VERSION__
28 #include "comedi.h"
29 #include <linux/uaccess.h> 28 #include <linux/uaccess.h>
30 29 #include "comedi.h"
31 #include "comedi_compat32.h" 30 #include "comedi_compat32.h"
32 31
33 #ifdef CONFIG_COMPAT 32 #ifdef CONFIG_COMPAT
34 33
35 #define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct) 34 #define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
36 #define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct) 35 #define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
37 /* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR. 36 /* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
38 * It's too late to change it now, but it only affects the command number. */ 37 * It's too late to change it now, but it only affects the command number. */
39 #define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct) 38 #define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
40 /* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR. 39 /* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
41 * It's too late to change it now, but it only affects the command number. */ 40 * It's too late to change it now, but it only affects the command number. */
42 #define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct) 41 #define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
43 #define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct) 42 #define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
44 #define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct) 43 #define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
45 44
46 struct comedi32_chaninfo_struct { 45 struct comedi32_chaninfo_struct {
47 unsigned int subdev; 46 unsigned int subdev;
48 compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */ 47 compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
49 compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */ 48 compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
50 compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */ 49 compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
51 unsigned int unused[4]; 50 unsigned int unused[4];
52 }; 51 };
53 52
54 struct comedi32_rangeinfo_struct { 53 struct comedi32_rangeinfo_struct {
55 unsigned int range_type; 54 unsigned int range_type;
56 compat_uptr_t range_ptr; /* 32-bit 'void *' */ 55 compat_uptr_t range_ptr; /* 32-bit 'void *' */
57 }; 56 };
58 57
59 struct comedi32_cmd_struct { 58 struct comedi32_cmd_struct {
60 unsigned int subdev; 59 unsigned int subdev;
61 unsigned int flags; 60 unsigned int flags;
62 unsigned int start_src; 61 unsigned int start_src;
63 unsigned int start_arg; 62 unsigned int start_arg;
64 unsigned int scan_begin_src; 63 unsigned int scan_begin_src;
65 unsigned int scan_begin_arg; 64 unsigned int scan_begin_arg;
66 unsigned int convert_src; 65 unsigned int convert_src;
67 unsigned int convert_arg; 66 unsigned int convert_arg;
68 unsigned int scan_end_src; 67 unsigned int scan_end_src;
69 unsigned int scan_end_arg; 68 unsigned int scan_end_arg;
70 unsigned int stop_src; 69 unsigned int stop_src;
71 unsigned int stop_arg; 70 unsigned int stop_arg;
72 compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */ 71 compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
73 unsigned int chanlist_len; 72 unsigned int chanlist_len;
74 compat_uptr_t data; /* 32-bit 'short *' */ 73 compat_uptr_t data; /* 32-bit 'short *' */
75 unsigned int data_len; 74 unsigned int data_len;
76 }; 75 };
77 76
78 struct comedi32_insn_struct { 77 struct comedi32_insn_struct {
79 unsigned int insn; 78 unsigned int insn;
80 unsigned int n; 79 unsigned int n;
81 compat_uptr_t data; /* 32-bit 'unsigned int *' */ 80 compat_uptr_t data; /* 32-bit 'unsigned int *' */
82 unsigned int subdev; 81 unsigned int subdev;
83 unsigned int chanspec; 82 unsigned int chanspec;
84 unsigned int unused[3]; 83 unsigned int unused[3];
85 }; 84 };
86 85
87 struct comedi32_insnlist_struct { 86 struct comedi32_insnlist_struct {
88 unsigned int n_insns; 87 unsigned int n_insns;
89 compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */ 88 compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
90 }; 89 };
91 90
92 /* Handle translated ioctl. */ 91 /* Handle translated ioctl. */
93 static int translated_ioctl(struct file *file, unsigned int cmd, 92 static int translated_ioctl(struct file *file, unsigned int cmd,
94 unsigned long arg) 93 unsigned long arg)
95 { 94 {
96 if (!file->f_op) 95 if (!file->f_op)
97 return -ENOTTY; 96 return -ENOTTY;
98 97
99 if (file->f_op->unlocked_ioctl) 98 if (file->f_op->unlocked_ioctl)
100 return file->f_op->unlocked_ioctl(file, cmd, arg); 99 return file->f_op->unlocked_ioctl(file, cmd, arg);
101 100
102 return -ENOTTY; 101 return -ENOTTY;
103 } 102 }
104 103
105 /* Handle 32-bit COMEDI_CHANINFO ioctl. */ 104 /* Handle 32-bit COMEDI_CHANINFO ioctl. */
106 static int compat_chaninfo(struct file *file, unsigned long arg) 105 static int compat_chaninfo(struct file *file, unsigned long arg)
107 { 106 {
108 struct comedi_chaninfo __user *chaninfo; 107 struct comedi_chaninfo __user *chaninfo;
109 struct comedi32_chaninfo_struct __user *chaninfo32; 108 struct comedi32_chaninfo_struct __user *chaninfo32;
110 int err; 109 int err;
111 union { 110 union {
112 unsigned int uint; 111 unsigned int uint;
113 compat_uptr_t uptr; 112 compat_uptr_t uptr;
114 } temp; 113 } temp;
115 114
116 chaninfo32 = compat_ptr(arg); 115 chaninfo32 = compat_ptr(arg);
117 chaninfo = compat_alloc_user_space(sizeof(*chaninfo)); 116 chaninfo = compat_alloc_user_space(sizeof(*chaninfo));
118 117
119 /* Copy chaninfo structure. Ignore unused members. */ 118 /* Copy chaninfo structure. Ignore unused members. */
120 if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32)) 119 if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32))
121 || !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo))) { 120 || !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo))) {
122 return -EFAULT; 121 return -EFAULT;
123 } 122 }
124 err = 0; 123 err = 0;
125 err |= __get_user(temp.uint, &chaninfo32->subdev); 124 err |= __get_user(temp.uint, &chaninfo32->subdev);
126 err |= __put_user(temp.uint, &chaninfo->subdev); 125 err |= __put_user(temp.uint, &chaninfo->subdev);
127 err |= __get_user(temp.uptr, &chaninfo32->maxdata_list); 126 err |= __get_user(temp.uptr, &chaninfo32->maxdata_list);
128 err |= __put_user(compat_ptr(temp.uptr), &chaninfo->maxdata_list); 127 err |= __put_user(compat_ptr(temp.uptr), &chaninfo->maxdata_list);
129 err |= __get_user(temp.uptr, &chaninfo32->flaglist); 128 err |= __get_user(temp.uptr, &chaninfo32->flaglist);
130 err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist); 129 err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist);
131 err |= __get_user(temp.uptr, &chaninfo32->rangelist); 130 err |= __get_user(temp.uptr, &chaninfo32->rangelist);
132 err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist); 131 err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist);
133 if (err) 132 if (err)
134 return -EFAULT; 133 return -EFAULT;
135 134
136 return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo); 135 return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo);
137 } 136 }
138 137
139 /* Handle 32-bit COMEDI_RANGEINFO ioctl. */ 138 /* Handle 32-bit COMEDI_RANGEINFO ioctl. */
140 static int compat_rangeinfo(struct file *file, unsigned long arg) 139 static int compat_rangeinfo(struct file *file, unsigned long arg)
141 { 140 {
142 struct comedi_rangeinfo __user *rangeinfo; 141 struct comedi_rangeinfo __user *rangeinfo;
143 struct comedi32_rangeinfo_struct __user *rangeinfo32; 142 struct comedi32_rangeinfo_struct __user *rangeinfo32;
144 int err; 143 int err;
145 union { 144 union {
146 unsigned int uint; 145 unsigned int uint;
147 compat_uptr_t uptr; 146 compat_uptr_t uptr;
148 } temp; 147 } temp;
149 148
150 rangeinfo32 = compat_ptr(arg); 149 rangeinfo32 = compat_ptr(arg);
151 rangeinfo = compat_alloc_user_space(sizeof(*rangeinfo)); 150 rangeinfo = compat_alloc_user_space(sizeof(*rangeinfo));
152 151
153 /* Copy rangeinfo structure. */ 152 /* Copy rangeinfo structure. */
154 if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32)) 153 if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32))
155 || !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo))) { 154 || !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo))) {
156 return -EFAULT; 155 return -EFAULT;
157 } 156 }
158 err = 0; 157 err = 0;
159 err |= __get_user(temp.uint, &rangeinfo32->range_type); 158 err |= __get_user(temp.uint, &rangeinfo32->range_type);
160 err |= __put_user(temp.uint, &rangeinfo->range_type); 159 err |= __put_user(temp.uint, &rangeinfo->range_type);
161 err |= __get_user(temp.uptr, &rangeinfo32->range_ptr); 160 err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
162 err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr); 161 err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
163 if (err) 162 if (err)
164 return -EFAULT; 163 return -EFAULT;
165 164
166 return translated_ioctl(file, COMEDI_RANGEINFO, 165 return translated_ioctl(file, COMEDI_RANGEINFO,
167 (unsigned long)rangeinfo); 166 (unsigned long)rangeinfo);
168 } 167 }
169 168
170 /* Copy 32-bit cmd structure to native cmd structure. */ 169 /* Copy 32-bit cmd structure to native cmd structure. */
171 static int get_compat_cmd(struct comedi_cmd __user *cmd, 170 static int get_compat_cmd(struct comedi_cmd __user *cmd,
172 struct comedi32_cmd_struct __user *cmd32) 171 struct comedi32_cmd_struct __user *cmd32)
173 { 172 {
174 int err; 173 int err;
175 union { 174 union {
176 unsigned int uint; 175 unsigned int uint;
177 compat_uptr_t uptr; 176 compat_uptr_t uptr;
178 } temp; 177 } temp;
179 178
180 /* Copy cmd structure. */ 179 /* Copy cmd structure. */
181 if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32)) 180 if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32))
182 || !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) { 181 || !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
183 return -EFAULT; 182 return -EFAULT;
184 } 183 }
185 err = 0; 184 err = 0;
186 err |= __get_user(temp.uint, &cmd32->subdev); 185 err |= __get_user(temp.uint, &cmd32->subdev);
187 err |= __put_user(temp.uint, &cmd->subdev); 186 err |= __put_user(temp.uint, &cmd->subdev);
188 err |= __get_user(temp.uint, &cmd32->flags); 187 err |= __get_user(temp.uint, &cmd32->flags);
189 err |= __put_user(temp.uint, &cmd->flags); 188 err |= __put_user(temp.uint, &cmd->flags);
190 err |= __get_user(temp.uint, &cmd32->start_src); 189 err |= __get_user(temp.uint, &cmd32->start_src);
191 err |= __put_user(temp.uint, &cmd->start_src); 190 err |= __put_user(temp.uint, &cmd->start_src);
192 err |= __get_user(temp.uint, &cmd32->start_arg); 191 err |= __get_user(temp.uint, &cmd32->start_arg);
193 err |= __put_user(temp.uint, &cmd->start_arg); 192 err |= __put_user(temp.uint, &cmd->start_arg);
194 err |= __get_user(temp.uint, &cmd32->scan_begin_src); 193 err |= __get_user(temp.uint, &cmd32->scan_begin_src);
195 err |= __put_user(temp.uint, &cmd->scan_begin_src); 194 err |= __put_user(temp.uint, &cmd->scan_begin_src);
196 err |= __get_user(temp.uint, &cmd32->scan_begin_arg); 195 err |= __get_user(temp.uint, &cmd32->scan_begin_arg);
197 err |= __put_user(temp.uint, &cmd->scan_begin_arg); 196 err |= __put_user(temp.uint, &cmd->scan_begin_arg);
198 err |= __get_user(temp.uint, &cmd32->convert_src); 197 err |= __get_user(temp.uint, &cmd32->convert_src);
199 err |= __put_user(temp.uint, &cmd->convert_src); 198 err |= __put_user(temp.uint, &cmd->convert_src);
200 err |= __get_user(temp.uint, &cmd32->convert_arg); 199 err |= __get_user(temp.uint, &cmd32->convert_arg);
201 err |= __put_user(temp.uint, &cmd->convert_arg); 200 err |= __put_user(temp.uint, &cmd->convert_arg);
202 err |= __get_user(temp.uint, &cmd32->scan_end_src); 201 err |= __get_user(temp.uint, &cmd32->scan_end_src);
203 err |= __put_user(temp.uint, &cmd->scan_end_src); 202 err |= __put_user(temp.uint, &cmd->scan_end_src);
204 err |= __get_user(temp.uint, &cmd32->scan_end_arg); 203 err |= __get_user(temp.uint, &cmd32->scan_end_arg);
205 err |= __put_user(temp.uint, &cmd->scan_end_arg); 204 err |= __put_user(temp.uint, &cmd->scan_end_arg);
206 err |= __get_user(temp.uint, &cmd32->stop_src); 205 err |= __get_user(temp.uint, &cmd32->stop_src);
207 err |= __put_user(temp.uint, &cmd->stop_src); 206 err |= __put_user(temp.uint, &cmd->stop_src);
208 err |= __get_user(temp.uint, &cmd32->stop_arg); 207 err |= __get_user(temp.uint, &cmd32->stop_arg);
209 err |= __put_user(temp.uint, &cmd->stop_arg); 208 err |= __put_user(temp.uint, &cmd->stop_arg);
210 err |= __get_user(temp.uptr, &cmd32->chanlist); 209 err |= __get_user(temp.uptr, &cmd32->chanlist);
211 err |= __put_user(compat_ptr(temp.uptr), &cmd->chanlist); 210 err |= __put_user(compat_ptr(temp.uptr), &cmd->chanlist);
212 err |= __get_user(temp.uint, &cmd32->chanlist_len); 211 err |= __get_user(temp.uint, &cmd32->chanlist_len);
213 err |= __put_user(temp.uint, &cmd->chanlist_len); 212 err |= __put_user(temp.uint, &cmd->chanlist_len);
214 err |= __get_user(temp.uptr, &cmd32->data); 213 err |= __get_user(temp.uptr, &cmd32->data);
215 err |= __put_user(compat_ptr(temp.uptr), &cmd->data); 214 err |= __put_user(compat_ptr(temp.uptr), &cmd->data);
216 err |= __get_user(temp.uint, &cmd32->data_len); 215 err |= __get_user(temp.uint, &cmd32->data_len);
217 err |= __put_user(temp.uint, &cmd->data_len); 216 err |= __put_user(temp.uint, &cmd->data_len);
218 return err ? -EFAULT : 0; 217 return err ? -EFAULT : 0;
219 } 218 }
220 219
221 /* Copy native cmd structure to 32-bit cmd structure. */ 220 /* Copy native cmd structure to 32-bit cmd structure. */
222 static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, 221 static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
223 struct comedi_cmd __user *cmd) 222 struct comedi_cmd __user *cmd)
224 { 223 {
225 int err; 224 int err;
226 unsigned int temp; 225 unsigned int temp;
227 226
228 /* Copy back most of cmd structure. */ 227 /* Copy back most of cmd structure. */
229 /* Assume the pointer values are already valid. */ 228 /* Assume the pointer values are already valid. */
230 /* (Could use ptr_to_compat() to set them, but that wasn't implemented 229 /* (Could use ptr_to_compat() to set them, but that wasn't implemented
231 * until kernel version 2.6.11.) */ 230 * until kernel version 2.6.11.) */
232 if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd)) 231 if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd))
233 || !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) { 232 || !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
234 return -EFAULT; 233 return -EFAULT;
235 } 234 }
236 err = 0; 235 err = 0;
237 err |= __get_user(temp, &cmd->subdev); 236 err |= __get_user(temp, &cmd->subdev);
238 err |= __put_user(temp, &cmd32->subdev); 237 err |= __put_user(temp, &cmd32->subdev);
239 err |= __get_user(temp, &cmd->flags); 238 err |= __get_user(temp, &cmd->flags);
240 err |= __put_user(temp, &cmd32->flags); 239 err |= __put_user(temp, &cmd32->flags);
241 err |= __get_user(temp, &cmd->start_src); 240 err |= __get_user(temp, &cmd->start_src);
242 err |= __put_user(temp, &cmd32->start_src); 241 err |= __put_user(temp, &cmd32->start_src);
243 err |= __get_user(temp, &cmd->start_arg); 242 err |= __get_user(temp, &cmd->start_arg);
244 err |= __put_user(temp, &cmd32->start_arg); 243 err |= __put_user(temp, &cmd32->start_arg);
245 err |= __get_user(temp, &cmd->scan_begin_src); 244 err |= __get_user(temp, &cmd->scan_begin_src);
246 err |= __put_user(temp, &cmd32->scan_begin_src); 245 err |= __put_user(temp, &cmd32->scan_begin_src);
247 err |= __get_user(temp, &cmd->scan_begin_arg); 246 err |= __get_user(temp, &cmd->scan_begin_arg);
248 err |= __put_user(temp, &cmd32->scan_begin_arg); 247 err |= __put_user(temp, &cmd32->scan_begin_arg);
249 err |= __get_user(temp, &cmd->convert_src); 248 err |= __get_user(temp, &cmd->convert_src);
250 err |= __put_user(temp, &cmd32->convert_src); 249 err |= __put_user(temp, &cmd32->convert_src);
251 err |= __get_user(temp, &cmd->convert_arg); 250 err |= __get_user(temp, &cmd->convert_arg);
252 err |= __put_user(temp, &cmd32->convert_arg); 251 err |= __put_user(temp, &cmd32->convert_arg);
253 err |= __get_user(temp, &cmd->scan_end_src); 252 err |= __get_user(temp, &cmd->scan_end_src);
254 err |= __put_user(temp, &cmd32->scan_end_src); 253 err |= __put_user(temp, &cmd32->scan_end_src);
255 err |= __get_user(temp, &cmd->scan_end_arg); 254 err |= __get_user(temp, &cmd->scan_end_arg);
256 err |= __put_user(temp, &cmd32->scan_end_arg); 255 err |= __put_user(temp, &cmd32->scan_end_arg);
257 err |= __get_user(temp, &cmd->stop_src); 256 err |= __get_user(temp, &cmd->stop_src);
258 err |= __put_user(temp, &cmd32->stop_src); 257 err |= __put_user(temp, &cmd32->stop_src);
259 err |= __get_user(temp, &cmd->stop_arg); 258 err |= __get_user(temp, &cmd->stop_arg);
260 err |= __put_user(temp, &cmd32->stop_arg); 259 err |= __put_user(temp, &cmd32->stop_arg);
261 /* Assume chanlist pointer is unchanged. */ 260 /* Assume chanlist pointer is unchanged. */
262 err |= __get_user(temp, &cmd->chanlist_len); 261 err |= __get_user(temp, &cmd->chanlist_len);
263 err |= __put_user(temp, &cmd32->chanlist_len); 262 err |= __put_user(temp, &cmd32->chanlist_len);
264 /* Assume data pointer is unchanged. */ 263 /* Assume data pointer is unchanged. */
265 err |= __get_user(temp, &cmd->data_len); 264 err |= __get_user(temp, &cmd->data_len);
266 err |= __put_user(temp, &cmd32->data_len); 265 err |= __put_user(temp, &cmd32->data_len);
267 return err ? -EFAULT : 0; 266 return err ? -EFAULT : 0;
268 } 267 }
269 268
270 /* Handle 32-bit COMEDI_CMD ioctl. */ 269 /* Handle 32-bit COMEDI_CMD ioctl. */
271 static int compat_cmd(struct file *file, unsigned long arg) 270 static int compat_cmd(struct file *file, unsigned long arg)
272 { 271 {
273 struct comedi_cmd __user *cmd; 272 struct comedi_cmd __user *cmd;
274 struct comedi32_cmd_struct __user *cmd32; 273 struct comedi32_cmd_struct __user *cmd32;
275 int rc; 274 int rc;
276 275
277 cmd32 = compat_ptr(arg); 276 cmd32 = compat_ptr(arg);
278 cmd = compat_alloc_user_space(sizeof(*cmd)); 277 cmd = compat_alloc_user_space(sizeof(*cmd));
279 278
280 rc = get_compat_cmd(cmd, cmd32); 279 rc = get_compat_cmd(cmd, cmd32);
281 if (rc) 280 if (rc)
282 return rc; 281 return rc;
283 282
284 return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd); 283 return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
285 } 284 }
286 285
287 /* Handle 32-bit COMEDI_CMDTEST ioctl. */ 286 /* Handle 32-bit COMEDI_CMDTEST ioctl. */
288 static int compat_cmdtest(struct file *file, unsigned long arg) 287 static int compat_cmdtest(struct file *file, unsigned long arg)
289 { 288 {
290 struct comedi_cmd __user *cmd; 289 struct comedi_cmd __user *cmd;
291 struct comedi32_cmd_struct __user *cmd32; 290 struct comedi32_cmd_struct __user *cmd32;
292 int rc, err; 291 int rc, err;
293 292
294 cmd32 = compat_ptr(arg); 293 cmd32 = compat_ptr(arg);
295 cmd = compat_alloc_user_space(sizeof(*cmd)); 294 cmd = compat_alloc_user_space(sizeof(*cmd));
296 295
297 rc = get_compat_cmd(cmd, cmd32); 296 rc = get_compat_cmd(cmd, cmd32);
298 if (rc) 297 if (rc)
299 return rc; 298 return rc;
300 299
301 rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd); 300 rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
302 if (rc < 0) 301 if (rc < 0)
303 return rc; 302 return rc;
304 303
305 err = put_compat_cmd(cmd32, cmd); 304 err = put_compat_cmd(cmd32, cmd);
306 if (err) 305 if (err)
307 rc = err; 306 rc = err;
308 307
309 return rc; 308 return rc;
310 } 309 }
311 310
312 /* Copy 32-bit insn structure to native insn structure. */ 311 /* Copy 32-bit insn structure to native insn structure. */
313 static int get_compat_insn(struct comedi_insn __user *insn, 312 static int get_compat_insn(struct comedi_insn __user *insn,
314 struct comedi32_insn_struct __user *insn32) 313 struct comedi32_insn_struct __user *insn32)
315 { 314 {
316 int err; 315 int err;
317 union { 316 union {
318 unsigned int uint; 317 unsigned int uint;
319 compat_uptr_t uptr; 318 compat_uptr_t uptr;
320 } temp; 319 } temp;
321 320
322 /* Copy insn structure. Ignore the unused members. */ 321 /* Copy insn structure. Ignore the unused members. */
323 err = 0; 322 err = 0;
324 if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32)) 323 if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
325 || !access_ok(VERIFY_WRITE, insn, sizeof(*insn))) 324 || !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
326 return -EFAULT; 325 return -EFAULT;
327 326
328 err |= __get_user(temp.uint, &insn32->insn); 327 err |= __get_user(temp.uint, &insn32->insn);
329 err |= __put_user(temp.uint, &insn->insn); 328 err |= __put_user(temp.uint, &insn->insn);
330 err |= __get_user(temp.uint, &insn32->n); 329 err |= __get_user(temp.uint, &insn32->n);
331 err |= __put_user(temp.uint, &insn->n); 330 err |= __put_user(temp.uint, &insn->n);
332 err |= __get_user(temp.uptr, &insn32->data); 331 err |= __get_user(temp.uptr, &insn32->data);
333 err |= __put_user(compat_ptr(temp.uptr), &insn->data); 332 err |= __put_user(compat_ptr(temp.uptr), &insn->data);
334 err |= __get_user(temp.uint, &insn32->subdev); 333 err |= __get_user(temp.uint, &insn32->subdev);
335 err |= __put_user(temp.uint, &insn->subdev); 334 err |= __put_user(temp.uint, &insn->subdev);
336 err |= __get_user(temp.uint, &insn32->chanspec); 335 err |= __get_user(temp.uint, &insn32->chanspec);
337 err |= __put_user(temp.uint, &insn->chanspec); 336 err |= __put_user(temp.uint, &insn->chanspec);
338 return err ? -EFAULT : 0; 337 return err ? -EFAULT : 0;
339 } 338 }
340 339
341 /* Handle 32-bit COMEDI_INSNLIST ioctl. */ 340 /* Handle 32-bit COMEDI_INSNLIST ioctl. */
342 static int compat_insnlist(struct file *file, unsigned long arg) 341 static int compat_insnlist(struct file *file, unsigned long arg)
343 { 342 {
344 struct combined_insnlist { 343 struct combined_insnlist {
345 struct comedi_insnlist insnlist; 344 struct comedi_insnlist insnlist;
346 struct comedi_insn insn[1]; 345 struct comedi_insn insn[1];
347 } __user *s; 346 } __user *s;
348 struct comedi32_insnlist_struct __user *insnlist32; 347 struct comedi32_insnlist_struct __user *insnlist32;
349 struct comedi32_insn_struct __user *insn32; 348 struct comedi32_insn_struct __user *insn32;
350 compat_uptr_t uptr; 349 compat_uptr_t uptr;
351 unsigned int n_insns, n; 350 unsigned int n_insns, n;
352 int err, rc; 351 int err, rc;
353 352
354 insnlist32 = compat_ptr(arg); 353 insnlist32 = compat_ptr(arg);
355 354
356 /* Get 32-bit insnlist structure. */ 355 /* Get 32-bit insnlist structure. */
357 if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32))) 356 if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32)))
358 return -EFAULT; 357 return -EFAULT;
359 358
360 err = 0; 359 err = 0;
361 err |= __get_user(n_insns, &insnlist32->n_insns); 360 err |= __get_user(n_insns, &insnlist32->n_insns);
362 err |= __get_user(uptr, &insnlist32->insns); 361 err |= __get_user(uptr, &insnlist32->insns);
363 insn32 = compat_ptr(uptr); 362 insn32 = compat_ptr(uptr);
364 if (err) 363 if (err)
365 return -EFAULT; 364 return -EFAULT;
366 365
367 /* Allocate user memory to copy insnlist and insns into. */ 366 /* Allocate user memory to copy insnlist and insns into. */
368 s = compat_alloc_user_space(offsetof(struct combined_insnlist, 367 s = compat_alloc_user_space(offsetof(struct combined_insnlist,
369 insn[n_insns])); 368 insn[n_insns]));
370 369
371 /* Set native insnlist structure. */ 370 /* Set native insnlist structure. */
372 if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) 371 if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist)))
373 return -EFAULT; 372 return -EFAULT;
374 373
375 err |= __put_user(n_insns, &s->insnlist.n_insns); 374 err |= __put_user(n_insns, &s->insnlist.n_insns);
376 err |= __put_user(&s->insn[0], &s->insnlist.insns); 375 err |= __put_user(&s->insn[0], &s->insnlist.insns);
377 if (err) 376 if (err)
378 return -EFAULT; 377 return -EFAULT;
379 378
380 /* Copy insn structures. */ 379 /* Copy insn structures. */
381 for (n = 0; n < n_insns; n++) { 380 for (n = 0; n < n_insns; n++) {
382 rc = get_compat_insn(&s->insn[n], &insn32[n]); 381 rc = get_compat_insn(&s->insn[n], &insn32[n]);
383 if (rc) 382 if (rc)
384 return rc; 383 return rc;
385 } 384 }
386 385
387 return translated_ioctl(file, COMEDI_INSNLIST, 386 return translated_ioctl(file, COMEDI_INSNLIST,
388 (unsigned long)&s->insnlist); 387 (unsigned long)&s->insnlist);
389 } 388 }
390 389
391 /* Handle 32-bit COMEDI_INSN ioctl. */ 390 /* Handle 32-bit COMEDI_INSN ioctl. */
392 static int compat_insn(struct file *file, unsigned long arg) 391 static int compat_insn(struct file *file, unsigned long arg)
393 { 392 {
394 struct comedi_insn __user *insn; 393 struct comedi_insn __user *insn;
395 struct comedi32_insn_struct __user *insn32; 394 struct comedi32_insn_struct __user *insn32;
396 int rc; 395 int rc;
397 396
398 insn32 = compat_ptr(arg); 397 insn32 = compat_ptr(arg);
399 insn = compat_alloc_user_space(sizeof(*insn)); 398 insn = compat_alloc_user_space(sizeof(*insn));
400 399
401 rc = get_compat_insn(insn, insn32); 400 rc = get_compat_insn(insn, insn32);
402 if (rc) 401 if (rc)
403 return rc; 402 return rc;
404 403
405 return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn); 404 return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
406 } 405 }
407 406
408 /* Process untranslated ioctl. */ 407 /* Process untranslated ioctl. */
409 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */ 408 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
410 static inline int raw_ioctl(struct file *file, unsigned int cmd, 409 static inline int raw_ioctl(struct file *file, unsigned int cmd,
411 unsigned long arg) 410 unsigned long arg)
412 { 411 {
413 int rc; 412 int rc;
414 413
415 switch (cmd) { 414 switch (cmd) {
416 case COMEDI_DEVCONFIG: 415 case COMEDI_DEVCONFIG:
417 case COMEDI_DEVINFO: 416 case COMEDI_DEVINFO:
418 case COMEDI_SUBDINFO: 417 case COMEDI_SUBDINFO:
419 case COMEDI_BUFCONFIG: 418 case COMEDI_BUFCONFIG:
420 case COMEDI_BUFINFO: 419 case COMEDI_BUFINFO:
421 /* Just need to translate the pointer argument. */ 420 /* Just need to translate the pointer argument. */
422 arg = (unsigned long)compat_ptr(arg); 421 arg = (unsigned long)compat_ptr(arg);
423 rc = translated_ioctl(file, cmd, arg); 422 rc = translated_ioctl(file, cmd, arg);
424 break; 423 break;
425 case COMEDI_LOCK: 424 case COMEDI_LOCK:
426 case COMEDI_UNLOCK: 425 case COMEDI_UNLOCK:
427 case COMEDI_CANCEL: 426 case COMEDI_CANCEL:
428 case COMEDI_POLL: 427 case COMEDI_POLL:
429 /* No translation needed. */ 428 /* No translation needed. */
430 rc = translated_ioctl(file, cmd, arg); 429 rc = translated_ioctl(file, cmd, arg);
431 break; 430 break;
432 case COMEDI32_CHANINFO: 431 case COMEDI32_CHANINFO:
433 rc = compat_chaninfo(file, arg); 432 rc = compat_chaninfo(file, arg);
434 break; 433 break;
435 case COMEDI32_RANGEINFO: 434 case COMEDI32_RANGEINFO:
436 rc = compat_rangeinfo(file, arg); 435 rc = compat_rangeinfo(file, arg);
437 break; 436 break;
438 case COMEDI32_CMD: 437 case COMEDI32_CMD:
439 rc = compat_cmd(file, arg); 438 rc = compat_cmd(file, arg);
440 break; 439 break;
441 case COMEDI32_CMDTEST: 440 case COMEDI32_CMDTEST:
442 rc = compat_cmdtest(file, arg); 441 rc = compat_cmdtest(file, arg);
443 break; 442 break;
444 case COMEDI32_INSNLIST: 443 case COMEDI32_INSNLIST:
445 rc = compat_insnlist(file, arg); 444 rc = compat_insnlist(file, arg);
446 break; 445 break;
447 case COMEDI32_INSN: 446 case COMEDI32_INSN:
448 rc = compat_insn(file, arg); 447 rc = compat_insn(file, arg);
449 break; 448 break;
450 default: 449 default:
451 rc = -ENOIOCTLCMD; 450 rc = -ENOIOCTLCMD;
452 break; 451 break;
453 } 452 }
454 return rc; 453 return rc;
455 } 454 }
456 455
457 /* compat_ioctl file operation. */ 456 /* compat_ioctl file operation. */
458 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */ 457 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
459 long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 458 long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
460 { 459 {
461 return raw_ioctl(file, cmd, arg); 460 return raw_ioctl(file, cmd, arg);
462 } 461 }
463 462
464 #endif /* CONFIG_COMPAT */ 463 #endif /* CONFIG_COMPAT */
465 464
drivers/staging/comedi/drivers/comedi_bond.c
1 /* 1 /*
2 comedi/drivers/comedi_bond.c 2 comedi/drivers/comedi_bond.c
3 A Comedi driver to 'bond' or merge multiple drivers and devices as one. 3 A Comedi driver to 'bond' or merge multiple drivers and devices as one.
4 4
5 COMEDI - Linux Control and Measurement Device Interface 5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7 Copyright (C) 2005 Calin A. Culianu <calin@ajvar.org> 7 Copyright (C) 2005 Calin A. Culianu <calin@ajvar.org>
8 8
9 This program is free software; you can redistribute it and/or modify 9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or 11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details. 17 GNU General Public License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software 20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 22
23 */ 23 */
24 /* 24 /*
25 Driver: comedi_bond 25 Driver: comedi_bond
26 Description: A driver to 'bond' (merge) multiple subdevices from multiple 26 Description: A driver to 'bond' (merge) multiple subdevices from multiple
27 devices together as one. 27 devices together as one.
28 Devices: 28 Devices:
29 Author: ds 29 Author: ds
30 Updated: Mon, 10 Oct 00:18:25 -0500 30 Updated: Mon, 10 Oct 00:18:25 -0500
31 Status: works 31 Status: works
32 32
33 This driver allows you to 'bond' (merge) multiple comedi subdevices 33 This driver allows you to 'bond' (merge) multiple comedi subdevices
34 (coming from possibly difference boards and/or drivers) together. For 34 (coming from possibly difference boards and/or drivers) together. For
35 example, if you had a board with 2 different DIO subdevices, and 35 example, if you had a board with 2 different DIO subdevices, and
36 another with 1 DIO subdevice, you could 'bond' them with this driver 36 another with 1 DIO subdevice, you could 'bond' them with this driver
37 so that they look like one big fat DIO subdevice. This makes writing 37 so that they look like one big fat DIO subdevice. This makes writing
38 applications slightly easier as you don't have to worry about managing 38 applications slightly easier as you don't have to worry about managing
39 different subdevices in the application -- you just worry about 39 different subdevices in the application -- you just worry about
40 indexing one linear array of channel id's. 40 indexing one linear array of channel id's.
41 41
42 Right now only DIO subdevices are supported as that's the personal itch 42 Right now only DIO subdevices are supported as that's the personal itch
43 I am scratching with this driver. If you want to add support for AI and AO 43 I am scratching with this driver. If you want to add support for AI and AO
44 subdevs, go right on ahead and do so! 44 subdevs, go right on ahead and do so!
45 45
46 Commands aren't supported -- although it would be cool if they were. 46 Commands aren't supported -- although it would be cool if they were.
47 47
48 Configuration Options: 48 Configuration Options:
49 List of comedi-minors to bond. All subdevices of the same type 49 List of comedi-minors to bond. All subdevices of the same type
50 within each minor will be concatenated together in the order given here. 50 within each minor will be concatenated together in the order given here.
51 */ 51 */
52 52
53 /* 53 /*
54 * The previous block comment is used to automatically generate 54 * The previous block comment is used to automatically generate
55 * documentation in Comedi and Comedilib. The fields: 55 * documentation in Comedi and Comedilib. The fields:
56 * 56 *
57 * Driver: the name of the driver 57 * Driver: the name of the driver
58 * Description: a short phrase describing the driver. Don't list boards. 58 * Description: a short phrase describing the driver. Don't list boards.
59 * Devices: a full list of the boards that attempt to be supported by 59 * Devices: a full list of the boards that attempt to be supported by
60 * the driver. Format is "(manufacturer) board name [comedi name]", 60 * the driver. Format is "(manufacturer) board name [comedi name]",
61 * where comedi_name is the name that is used to configure the board. 61 * where comedi_name is the name that is used to configure the board.
62 * See the comment near board_name: in the struct comedi_driver structure 62 * See the comment near board_name: in the struct comedi_driver structure
63 * below. If (manufacturer) or [comedi name] is missing, the previous 63 * below. If (manufacturer) or [comedi name] is missing, the previous
64 * value is used. 64 * value is used.
65 * Author: you 65 * Author: you
66 * Updated: date when the _documentation_ was last updated. Use 'date -R' 66 * Updated: date when the _documentation_ was last updated. Use 'date -R'
67 * to get a value for this. 67 * to get a value for this.
68 * Status: a one-word description of the status. Valid values are: 68 * Status: a one-word description of the status. Valid values are:
69 * works - driver works correctly on most boards supported, and 69 * works - driver works correctly on most boards supported, and
70 * passes comedi_test. 70 * passes comedi_test.
71 * unknown - unknown. Usually put there by ds. 71 * unknown - unknown. Usually put there by ds.
72 * experimental - may not work in any particular release. Author 72 * experimental - may not work in any particular release. Author
73 * probably wants assistance testing it. 73 * probably wants assistance testing it.
74 * bitrotten - driver has not been update in a long time, probably 74 * bitrotten - driver has not been update in a long time, probably
75 * doesn't work, and probably is missing support for significant 75 * doesn't work, and probably is missing support for significant
76 * Comedi interface features. 76 * Comedi interface features.
77 * untested - author probably wrote it "blind", and is believed to 77 * untested - author probably wrote it "blind", and is believed to
78 * work, but no confirmation. 78 * work, but no confirmation.
79 * 79 *
80 * These headers should be followed by a blank line, and any comments 80 * These headers should be followed by a blank line, and any comments
81 * you wish to say about the driver. The comment area is the place 81 * you wish to say about the driver. The comment area is the place
82 * to put any known bugs, limitations, unsupported features, supported 82 * to put any known bugs, limitations, unsupported features, supported
83 * command triggers, whether or not commands are supported on particular 83 * command triggers, whether or not commands are supported on particular
84 * subdevices, etc. 84 * subdevices, etc.
85 * 85 *
86 * Somewhere in the comment should be information about configuration 86 * Somewhere in the comment should be information about configuration
87 * options that are used with comedi_config. 87 * options that are used with comedi_config.
88 */ 88 */
89 89
90 #include <linux/string.h>
91 #include <linux/slab.h>
90 #include "../comedi.h" 92 #include "../comedi.h"
91 #include "../comedilib.h" 93 #include "../comedilib.h"
92 #include "../comedidev.h" 94 #include "../comedidev.h"
93 #include <linux/string.h>
94 #include <linux/slab.h>
95 95
96 /* The maxiumum number of channels per subdevice. */ 96 /* The maxiumum number of channels per subdevice. */
97 #define MAX_CHANS 256 97 #define MAX_CHANS 256
98 98
99 #define MODULE_NAME "comedi_bond" 99 #define MODULE_NAME "comedi_bond"
100 MODULE_LICENSE("GPL"); 100 MODULE_LICENSE("GPL");
101 #ifndef STR 101 #ifndef STR
102 # define STR1(x) #x 102 # define STR1(x) #x
103 # define STR(x) STR1(x) 103 # define STR(x) STR1(x)
104 #endif 104 #endif
105 105
106 static int debug; 106 static int debug;
107 module_param(debug, int, 0644); 107 module_param(debug, int, 0644);
108 MODULE_PARM_DESC(debug, "If true, print extra cryptic debugging output useful" 108 MODULE_PARM_DESC(debug, "If true, print extra cryptic debugging output useful"
109 "only to developers."); 109 "only to developers.");
110 110
111 #define LOG_MSG(x...) printk(KERN_INFO MODULE_NAME": "x) 111 #define LOG_MSG(x...) printk(KERN_INFO MODULE_NAME": "x)
112 #define DEBUG(x...) \ 112 #define DEBUG(x...) \
113 do { \ 113 do { \
114 if (debug) \ 114 if (debug) \
115 printk(KERN_DEBUG MODULE_NAME": DEBUG: "x); \ 115 printk(KERN_DEBUG MODULE_NAME": DEBUG: "x); \
116 } while (0) 116 } while (0)
117 #define WARNING(x...) printk(KERN_WARNING MODULE_NAME ": WARNING: "x) 117 #define WARNING(x...) printk(KERN_WARNING MODULE_NAME ": WARNING: "x)
118 #define ERROR(x...) printk(KERN_ERR MODULE_NAME ": INTERNAL ERROR: "x) 118 #define ERROR(x...) printk(KERN_ERR MODULE_NAME ": INTERNAL ERROR: "x)
119 MODULE_AUTHOR("Calin A. Culianu"); 119 MODULE_AUTHOR("Calin A. Culianu");
120 MODULE_DESCRIPTION(MODULE_NAME "A driver for COMEDI to bond multiple COMEDI " 120 MODULE_DESCRIPTION(MODULE_NAME "A driver for COMEDI to bond multiple COMEDI "
121 "devices together as one. In the words of John Lennon: " 121 "devices together as one. In the words of John Lennon: "
122 "'And the world will live as one...'"); 122 "'And the world will live as one...'");
123 123
124 /* 124 /*
125 * Board descriptions for two imaginary boards. Describing the 125 * Board descriptions for two imaginary boards. Describing the
126 * boards in this way is optional, and completely driver-dependent. 126 * boards in this way is optional, and completely driver-dependent.
127 * Some drivers use arrays such as this, other do not. 127 * Some drivers use arrays such as this, other do not.
128 */ 128 */
129 struct BondingBoard { 129 struct BondingBoard {
130 const char *name; 130 const char *name;
131 }; 131 };
132 132
133 static const struct BondingBoard bondingBoards[] = { 133 static const struct BondingBoard bondingBoards[] = {
134 { 134 {
135 .name = MODULE_NAME, 135 .name = MODULE_NAME,
136 }, 136 },
137 }; 137 };
138 138
139 /* 139 /*
140 * Useful for shorthand access to the particular board structure 140 * Useful for shorthand access to the particular board structure
141 */ 141 */
142 #define thisboard ((const struct BondingBoard *)dev->board_ptr) 142 #define thisboard ((const struct BondingBoard *)dev->board_ptr)
143 143
144 struct BondedDevice { 144 struct BondedDevice {
145 struct comedi_device *dev; 145 struct comedi_device *dev;
146 unsigned minor; 146 unsigned minor;
147 unsigned subdev; 147 unsigned subdev;
148 unsigned subdev_type; 148 unsigned subdev_type;
149 unsigned nchans; 149 unsigned nchans;
150 unsigned chanid_offset; /* The offset into our unified linear 150 unsigned chanid_offset; /* The offset into our unified linear
151 channel-id's of chanid 0 on this 151 channel-id's of chanid 0 on this
152 subdevice. */ 152 subdevice. */
153 }; 153 };
154 154
155 /* this structure is for data unique to this hardware driver. If 155 /* this structure is for data unique to this hardware driver. If
156 several hardware drivers keep similar information in this structure, 156 several hardware drivers keep similar information in this structure,
157 feel free to suggest moving the variable to the struct comedi_device struct. */ 157 feel free to suggest moving the variable to the struct comedi_device struct. */
158 struct Private { 158 struct Private {
159 # define MAX_BOARD_NAME 256 159 # define MAX_BOARD_NAME 256
160 char name[MAX_BOARD_NAME]; 160 char name[MAX_BOARD_NAME];
161 struct BondedDevice **devs; 161 struct BondedDevice **devs;
162 unsigned ndevs; 162 unsigned ndevs;
163 struct BondedDevice *chanIdDevMap[MAX_CHANS]; 163 struct BondedDevice *chanIdDevMap[MAX_CHANS];
164 unsigned nchans; 164 unsigned nchans;
165 }; 165 };
166 166
167 /* 167 /*
168 * most drivers define the following macro to make it easy to 168 * most drivers define the following macro to make it easy to
169 * access the private structure. 169 * access the private structure.
170 */ 170 */
171 #define devpriv ((struct Private *)dev->private) 171 #define devpriv ((struct Private *)dev->private)
172 172
173 /* 173 /*
174 * The struct comedi_driver structure tells the Comedi core module 174 * The struct comedi_driver structure tells the Comedi core module
175 * which functions to call to configure/deconfigure (attach/detach) 175 * which functions to call to configure/deconfigure (attach/detach)
176 * the board, and also about the kernel module that contains 176 * the board, and also about the kernel module that contains
177 * the device code. 177 * the device code.
178 */ 178 */
179 static int bonding_attach(struct comedi_device *dev, 179 static int bonding_attach(struct comedi_device *dev,
180 struct comedi_devconfig *it); 180 struct comedi_devconfig *it);
181 static int bonding_detach(struct comedi_device *dev); 181 static int bonding_detach(struct comedi_device *dev);
182 /** Build Private array of all devices.. */ 182 /** Build Private array of all devices.. */
183 static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it); 183 static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it);
184 static void doDevUnconfig(struct comedi_device *dev); 184 static void doDevUnconfig(struct comedi_device *dev);
185 /* Ugly implementation of realloc that always copies memory around -- I'm lazy, 185 /* Ugly implementation of realloc that always copies memory around -- I'm lazy,
186 * what can I say? I like to do wasteful memcopies.. :) */ 186 * what can I say? I like to do wasteful memcopies.. :) */
187 static void *Realloc(const void *ptr, size_t len, size_t old_len); 187 static void *Realloc(const void *ptr, size_t len, size_t old_len);
188 188
189 static struct comedi_driver driver_bonding = { 189 static struct comedi_driver driver_bonding = {
190 .driver_name = MODULE_NAME, 190 .driver_name = MODULE_NAME,
191 .module = THIS_MODULE, 191 .module = THIS_MODULE,
192 .attach = bonding_attach, 192 .attach = bonding_attach,
193 .detach = bonding_detach, 193 .detach = bonding_detach,
194 /* It is not necessary to implement the following members if you are 194 /* It is not necessary to implement the following members if you are
195 * writing a driver for a ISA PnP or PCI card */ 195 * writing a driver for a ISA PnP or PCI card */
196 /* Most drivers will support multiple types of boards by 196 /* Most drivers will support multiple types of boards by
197 * having an array of board structures. These were defined 197 * having an array of board structures. These were defined
198 * in skel_boards[] above. Note that the element 'name' 198 * in skel_boards[] above. Note that the element 'name'
199 * was first in the structure -- Comedi uses this fact to 199 * was first in the structure -- Comedi uses this fact to
200 * extract the name of the board without knowing any details 200 * extract the name of the board without knowing any details
201 * about the structure except for its length. 201 * about the structure except for its length.
202 * When a device is attached (by comedi_config), the name 202 * When a device is attached (by comedi_config), the name
203 * of the device is given to Comedi, and Comedi tries to 203 * of the device is given to Comedi, and Comedi tries to
204 * match it by going through the list of board names. If 204 * match it by going through the list of board names. If
205 * there is a match, the address of the pointer is put 205 * there is a match, the address of the pointer is put
206 * into dev->board_ptr and driver->attach() is called. 206 * into dev->board_ptr and driver->attach() is called.
207 * 207 *
208 * Note that these are not necessary if you can determine 208 * Note that these are not necessary if you can determine
209 * the type of board in software. ISA PnP, PCI, and PCMCIA 209 * the type of board in software. ISA PnP, PCI, and PCMCIA
210 * devices are such boards. 210 * devices are such boards.
211 */ 211 */
212 .board_name = &bondingBoards[0].name, 212 .board_name = &bondingBoards[0].name,
213 .offset = sizeof(struct BondingBoard), 213 .offset = sizeof(struct BondingBoard),
214 .num_names = ARRAY_SIZE(bondingBoards), 214 .num_names = ARRAY_SIZE(bondingBoards),
215 }; 215 };
216 216
217 static int bonding_dio_insn_bits(struct comedi_device *dev, 217 static int bonding_dio_insn_bits(struct comedi_device *dev,
218 struct comedi_subdevice *s, 218 struct comedi_subdevice *s,
219 struct comedi_insn *insn, unsigned int *data); 219 struct comedi_insn *insn, unsigned int *data);
220 static int bonding_dio_insn_config(struct comedi_device *dev, 220 static int bonding_dio_insn_config(struct comedi_device *dev,
221 struct comedi_subdevice *s, 221 struct comedi_subdevice *s,
222 struct comedi_insn *insn, 222 struct comedi_insn *insn,
223 unsigned int *data); 223 unsigned int *data);
224 224
225 /* 225 /*
226 * Attach is called by the Comedi core to configure the driver 226 * Attach is called by the Comedi core to configure the driver
227 * for a particular board. If you specified a board_name array 227 * for a particular board. If you specified a board_name array
228 * in the driver structure, dev->board_ptr contains that 228 * in the driver structure, dev->board_ptr contains that
229 * address. 229 * address.
230 */ 230 */
231 static int bonding_attach(struct comedi_device *dev, 231 static int bonding_attach(struct comedi_device *dev,
232 struct comedi_devconfig *it) 232 struct comedi_devconfig *it)
233 { 233 {
234 struct comedi_subdevice *s; 234 struct comedi_subdevice *s;
235 235
236 LOG_MSG("comedi%d\n", dev->minor); 236 LOG_MSG("comedi%d\n", dev->minor);
237 237
238 /* 238 /*
239 * Allocate the private structure area. alloc_private() is a 239 * Allocate the private structure area. alloc_private() is a
240 * convenient macro defined in comedidev.h. 240 * convenient macro defined in comedidev.h.
241 */ 241 */
242 if (alloc_private(dev, sizeof(struct Private)) < 0) 242 if (alloc_private(dev, sizeof(struct Private)) < 0)
243 return -ENOMEM; 243 return -ENOMEM;
244 244
245 /* 245 /*
246 * Setup our bonding from config params.. sets up our Private struct.. 246 * Setup our bonding from config params.. sets up our Private struct..
247 */ 247 */
248 if (!doDevConfig(dev, it)) 248 if (!doDevConfig(dev, it))
249 return -EINVAL; 249 return -EINVAL;
250 250
251 /* 251 /*
252 * Initialize dev->board_name. Note that we can use the "thisboard" 252 * Initialize dev->board_name. Note that we can use the "thisboard"
253 * macro now, since we just initialized it in the last line. 253 * macro now, since we just initialized it in the last line.
254 */ 254 */
255 dev->board_name = devpriv->name; 255 dev->board_name = devpriv->name;
256 256
257 /* 257 /*
258 * Allocate the subdevice structures. alloc_subdevice() is a 258 * Allocate the subdevice structures. alloc_subdevice() is a
259 * convenient macro defined in comedidev.h. 259 * convenient macro defined in comedidev.h.
260 */ 260 */
261 if (alloc_subdevices(dev, 1) < 0) 261 if (alloc_subdevices(dev, 1) < 0)
262 return -ENOMEM; 262 return -ENOMEM;
263 263
264 s = dev->subdevices + 0; 264 s = dev->subdevices + 0;
265 s->type = COMEDI_SUBD_DIO; 265 s->type = COMEDI_SUBD_DIO;
266 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 266 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
267 s->n_chan = devpriv->nchans; 267 s->n_chan = devpriv->nchans;
268 s->maxdata = 1; 268 s->maxdata = 1;
269 s->range_table = &range_digital; 269 s->range_table = &range_digital;
270 s->insn_bits = bonding_dio_insn_bits; 270 s->insn_bits = bonding_dio_insn_bits;
271 s->insn_config = bonding_dio_insn_config; 271 s->insn_config = bonding_dio_insn_config;
272 272
273 LOG_MSG("attached with %u DIO channels coming from %u different " 273 LOG_MSG("attached with %u DIO channels coming from %u different "
274 "subdevices all bonded together. " 274 "subdevices all bonded together. "
275 "John Lennon would be proud!\n", 275 "John Lennon would be proud!\n",
276 devpriv->nchans, devpriv->ndevs); 276 devpriv->nchans, devpriv->ndevs);
277 277
278 return 1; 278 return 1;
279 } 279 }
280 280
281 /* 281 /*
282 * _detach is called to deconfigure a device. It should deallocate 282 * _detach is called to deconfigure a device. It should deallocate
283 * resources. 283 * resources.
284 * This function is also called when _attach() fails, so it should be 284 * This function is also called when _attach() fails, so it should be
285 * careful not to release resources that were not necessarily 285 * careful not to release resources that were not necessarily
286 * allocated by _attach(). dev->private and dev->subdevices are 286 * allocated by _attach(). dev->private and dev->subdevices are
287 * deallocated automatically by the core. 287 * deallocated automatically by the core.
288 */ 288 */
289 static int bonding_detach(struct comedi_device *dev) 289 static int bonding_detach(struct comedi_device *dev)
290 { 290 {
291 LOG_MSG("comedi%d: remove\n", dev->minor); 291 LOG_MSG("comedi%d: remove\n", dev->minor);
292 doDevUnconfig(dev); 292 doDevUnconfig(dev);
293 return 0; 293 return 0;
294 } 294 }
295 295
296 /* DIO devices are slightly special. Although it is possible to 296 /* DIO devices are slightly special. Although it is possible to
297 * implement the insn_read/insn_write interface, it is much more 297 * implement the insn_read/insn_write interface, it is much more
298 * useful to applications if you implement the insn_bits interface. 298 * useful to applications if you implement the insn_bits interface.
299 * This allows packed reading/writing of the DIO channels. The 299 * This allows packed reading/writing of the DIO channels. The
300 * comedi core can convert between insn_bits and insn_read/write */ 300 * comedi core can convert between insn_bits and insn_read/write */
301 static int bonding_dio_insn_bits(struct comedi_device *dev, 301 static int bonding_dio_insn_bits(struct comedi_device *dev,
302 struct comedi_subdevice *s, 302 struct comedi_subdevice *s,
303 struct comedi_insn *insn, unsigned int *data) 303 struct comedi_insn *insn, unsigned int *data)
304 { 304 {
305 #define LSAMPL_BITS (sizeof(unsigned int)*8) 305 #define LSAMPL_BITS (sizeof(unsigned int)*8)
306 unsigned nchans = LSAMPL_BITS, num_done = 0, i; 306 unsigned nchans = LSAMPL_BITS, num_done = 0, i;
307 if (insn->n != 2) 307 if (insn->n != 2)
308 return -EINVAL; 308 return -EINVAL;
309 309
310 if (devpriv->nchans < nchans) 310 if (devpriv->nchans < nchans)
311 nchans = devpriv->nchans; 311 nchans = devpriv->nchans;
312 312
313 /* The insn data is a mask in data[0] and the new data 313 /* The insn data is a mask in data[0] and the new data
314 * in data[1], each channel cooresponding to a bit. */ 314 * in data[1], each channel cooresponding to a bit. */
315 for (i = 0; num_done < nchans && i < devpriv->ndevs; ++i) { 315 for (i = 0; num_done < nchans && i < devpriv->ndevs; ++i) {
316 struct BondedDevice *bdev = devpriv->devs[i]; 316 struct BondedDevice *bdev = devpriv->devs[i];
317 /* Grab the channel mask and data of only the bits corresponding 317 /* Grab the channel mask and data of only the bits corresponding
318 to this subdevice.. need to shift them to zero position of 318 to this subdevice.. need to shift them to zero position of
319 course. */ 319 course. */
320 /* Bits corresponding to this subdev. */ 320 /* Bits corresponding to this subdev. */
321 unsigned int subdevMask = ((1 << bdev->nchans) - 1); 321 unsigned int subdevMask = ((1 << bdev->nchans) - 1);
322 unsigned int writeMask, dataBits; 322 unsigned int writeMask, dataBits;
323 323
324 /* Argh, we have >= LSAMPL_BITS chans.. take all bits */ 324 /* Argh, we have >= LSAMPL_BITS chans.. take all bits */
325 if (bdev->nchans >= LSAMPL_BITS) 325 if (bdev->nchans >= LSAMPL_BITS)
326 subdevMask = (unsigned int)(-1); 326 subdevMask = (unsigned int)(-1);
327 327
328 writeMask = (data[0] >> num_done) & subdevMask; 328 writeMask = (data[0] >> num_done) & subdevMask;
329 dataBits = (data[1] >> num_done) & subdevMask; 329 dataBits = (data[1] >> num_done) & subdevMask;
330 330
331 /* Read/Write the new digital lines */ 331 /* Read/Write the new digital lines */
332 if (comedi_dio_bitfield(bdev->dev, bdev->subdev, writeMask, 332 if (comedi_dio_bitfield(bdev->dev, bdev->subdev, writeMask,
333 &dataBits) != 2) 333 &dataBits) != 2)
334 return -EINVAL; 334 return -EINVAL;
335 335
336 /* Make room for the new bits in data[1], the return value */ 336 /* Make room for the new bits in data[1], the return value */
337 data[1] &= ~(subdevMask << num_done); 337 data[1] &= ~(subdevMask << num_done);
338 /* Put the bits in the return value */ 338 /* Put the bits in the return value */
339 data[1] |= (dataBits & subdevMask) << num_done; 339 data[1] |= (dataBits & subdevMask) << num_done;
340 /* Save the new bits to the saved state.. */ 340 /* Save the new bits to the saved state.. */
341 s->state = data[1]; 341 s->state = data[1];
342 342
343 num_done += bdev->nchans; 343 num_done += bdev->nchans;
344 } 344 }
345 345
346 return insn->n; 346 return insn->n;
347 } 347 }
348 348
349 static int bonding_dio_insn_config(struct comedi_device *dev, 349 static int bonding_dio_insn_config(struct comedi_device *dev,
350 struct comedi_subdevice *s, 350 struct comedi_subdevice *s,
351 struct comedi_insn *insn, unsigned int *data) 351 struct comedi_insn *insn, unsigned int *data)
352 { 352 {
353 int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits; 353 int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
354 unsigned int io; 354 unsigned int io;
355 struct BondedDevice *bdev; 355 struct BondedDevice *bdev;
356 356
357 if (chan < 0 || chan >= devpriv->nchans) 357 if (chan < 0 || chan >= devpriv->nchans)
358 return -EINVAL; 358 return -EINVAL;
359 bdev = devpriv->chanIdDevMap[chan]; 359 bdev = devpriv->chanIdDevMap[chan];
360 360
361 /* The input or output configuration of each digital line is 361 /* The input or output configuration of each digital line is
362 * configured by a special insn_config instruction. chanspec 362 * configured by a special insn_config instruction. chanspec
363 * contains the channel to be changed, and data[0] contains the 363 * contains the channel to be changed, and data[0] contains the
364 * value COMEDI_INPUT or COMEDI_OUTPUT. */ 364 * value COMEDI_INPUT or COMEDI_OUTPUT. */
365 switch (data[0]) { 365 switch (data[0]) {
366 case INSN_CONFIG_DIO_OUTPUT: 366 case INSN_CONFIG_DIO_OUTPUT:
367 io = COMEDI_OUTPUT; /* is this really necessary? */ 367 io = COMEDI_OUTPUT; /* is this really necessary? */
368 io_bits |= 1 << chan; 368 io_bits |= 1 << chan;
369 break; 369 break;
370 case INSN_CONFIG_DIO_INPUT: 370 case INSN_CONFIG_DIO_INPUT:
371 io = COMEDI_INPUT; /* is this really necessary? */ 371 io = COMEDI_INPUT; /* is this really necessary? */
372 io_bits &= ~(1 << chan); 372 io_bits &= ~(1 << chan);
373 break; 373 break;
374 case INSN_CONFIG_DIO_QUERY: 374 case INSN_CONFIG_DIO_QUERY:
375 data[1] = 375 data[1] =
376 (io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; 376 (io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
377 return insn->n; 377 return insn->n;
378 break; 378 break;
379 default: 379 default:
380 return -EINVAL; 380 return -EINVAL;
381 break; 381 break;
382 } 382 }
383 /* 'real' channel id for this subdev.. */ 383 /* 'real' channel id for this subdev.. */
384 chan -= bdev->chanid_offset; 384 chan -= bdev->chanid_offset;
385 ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, io); 385 ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, io);
386 if (ret != 1) 386 if (ret != 1)
387 return -EINVAL; 387 return -EINVAL;
388 /* Finally, save the new io_bits values since we didn't get 388 /* Finally, save the new io_bits values since we didn't get
389 an error above. */ 389 an error above. */
390 s->io_bits = io_bits; 390 s->io_bits = io_bits;
391 return insn->n; 391 return insn->n;
392 } 392 }
393 393
394 static void *Realloc(const void *oldmem, size_t newlen, size_t oldlen) 394 static void *Realloc(const void *oldmem, size_t newlen, size_t oldlen)
395 { 395 {
396 void *newmem = kmalloc(newlen, GFP_KERNEL); 396 void *newmem = kmalloc(newlen, GFP_KERNEL);
397 397
398 if (newmem && oldmem) 398 if (newmem && oldmem)
399 memcpy(newmem, oldmem, min(oldlen, newlen)); 399 memcpy(newmem, oldmem, min(oldlen, newlen));
400 kfree(oldmem); 400 kfree(oldmem);
401 return newmem; 401 return newmem;
402 } 402 }
403 403
404 static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) 404 static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
405 { 405 {
406 int i; 406 int i;
407 struct comedi_device *devs_opened[COMEDI_NUM_BOARD_MINORS]; 407 struct comedi_device *devs_opened[COMEDI_NUM_BOARD_MINORS];
408 408
409 memset(devs_opened, 0, sizeof(devs_opened)); 409 memset(devs_opened, 0, sizeof(devs_opened));
410 devpriv->name[0] = 0;; 410 devpriv->name[0] = 0;;
411 /* Loop through all comedi devices specified on the command-line, 411 /* Loop through all comedi devices specified on the command-line,
412 building our device list */ 412 building our device list */
413 for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) { 413 for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) {
414 char file[] = "/dev/comediXXXXXX"; 414 char file[] = "/dev/comediXXXXXX";
415 int minor = it->options[i]; 415 int minor = it->options[i];
416 struct comedi_device *d; 416 struct comedi_device *d;
417 int sdev = -1, nchans, tmp; 417 int sdev = -1, nchans, tmp;
418 struct BondedDevice *bdev = NULL; 418 struct BondedDevice *bdev = NULL;
419 419
420 if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) { 420 if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) {
421 ERROR("Minor %d is invalid!\n", minor); 421 ERROR("Minor %d is invalid!\n", minor);
422 return 0; 422 return 0;
423 } 423 }
424 if (minor == dev->minor) { 424 if (minor == dev->minor) {
425 ERROR("Cannot bond this driver to itself!\n"); 425 ERROR("Cannot bond this driver to itself!\n");
426 return 0; 426 return 0;
427 } 427 }
428 if (devs_opened[minor]) { 428 if (devs_opened[minor]) {
429 ERROR("Minor %d specified more than once!\n", minor); 429 ERROR("Minor %d specified more than once!\n", minor);
430 return 0; 430 return 0;
431 } 431 }
432 432
433 snprintf(file, sizeof(file), "/dev/comedi%u", minor); 433 snprintf(file, sizeof(file), "/dev/comedi%u", minor);
434 file[sizeof(file) - 1] = 0; 434 file[sizeof(file) - 1] = 0;
435 435
436 d = devs_opened[minor] = comedi_open(file); 436 d = devs_opened[minor] = comedi_open(file);
437 437
438 if (!d) { 438 if (!d) {
439 ERROR("Minor %u could not be opened\n", minor); 439 ERROR("Minor %u could not be opened\n", minor);
440 return 0; 440 return 0;
441 } 441 }
442 442
443 /* Do DIO, as that's all we support now.. */ 443 /* Do DIO, as that's all we support now.. */
444 while ((sdev = comedi_find_subdevice_by_type(d, COMEDI_SUBD_DIO, 444 while ((sdev = comedi_find_subdevice_by_type(d, COMEDI_SUBD_DIO,
445 sdev + 1)) > -1) { 445 sdev + 1)) > -1) {
446 nchans = comedi_get_n_channels(d, sdev); 446 nchans = comedi_get_n_channels(d, sdev);
447 if (nchans <= 0) { 447 if (nchans <= 0) {
448 ERROR("comedi_get_n_channels() returned %d " 448 ERROR("comedi_get_n_channels() returned %d "
449 "on minor %u subdev %d!\n", 449 "on minor %u subdev %d!\n",
450 nchans, minor, sdev); 450 nchans, minor, sdev);
451 return 0; 451 return 0;
452 } 452 }
453 bdev = kmalloc(sizeof(*bdev), GFP_KERNEL); 453 bdev = kmalloc(sizeof(*bdev), GFP_KERNEL);
454 if (!bdev) { 454 if (!bdev) {
455 ERROR("Out of memory.\n"); 455 ERROR("Out of memory.\n");
456 return 0; 456 return 0;
457 } 457 }
458 bdev->dev = d; 458 bdev->dev = d;
459 bdev->minor = minor; 459 bdev->minor = minor;
460 bdev->subdev = sdev; 460 bdev->subdev = sdev;
461 bdev->subdev_type = COMEDI_SUBD_DIO; 461 bdev->subdev_type = COMEDI_SUBD_DIO;
462 bdev->nchans = nchans; 462 bdev->nchans = nchans;
463 bdev->chanid_offset = devpriv->nchans; 463 bdev->chanid_offset = devpriv->nchans;
464 464
465 /* map channel id's to BondedDevice * pointer.. */ 465 /* map channel id's to BondedDevice * pointer.. */
466 while (nchans--) 466 while (nchans--)
467 devpriv->chanIdDevMap[devpriv->nchans++] = bdev; 467 devpriv->chanIdDevMap[devpriv->nchans++] = bdev;
468 468
469 /* Now put bdev pointer at end of devpriv->devs array 469 /* Now put bdev pointer at end of devpriv->devs array
470 * list.. */ 470 * list.. */
471 471
472 /* ergh.. ugly.. we need to realloc :( */ 472 /* ergh.. ugly.. we need to realloc :( */
473 tmp = devpriv->ndevs * sizeof(bdev); 473 tmp = devpriv->ndevs * sizeof(bdev);
474 devpriv->devs = 474 devpriv->devs =
475 Realloc(devpriv->devs, 475 Realloc(devpriv->devs,
476 ++devpriv->ndevs * sizeof(bdev), tmp); 476 ++devpriv->ndevs * sizeof(bdev), tmp);
477 if (!devpriv->devs) { 477 if (!devpriv->devs) {
478 ERROR("Could not allocate memory. " 478 ERROR("Could not allocate memory. "
479 "Out of memory?"); 479 "Out of memory?");
480 return 0; 480 return 0;
481 } 481 }
482 482
483 devpriv->devs[devpriv->ndevs - 1] = bdev; 483 devpriv->devs[devpriv->ndevs - 1] = bdev;
484 { 484 {
485 /** Append dev:subdev to devpriv->name */ 485 /** Append dev:subdev to devpriv->name */
486 char buf[20]; 486 char buf[20];
487 int left = 487 int left =
488 MAX_BOARD_NAME - strlen(devpriv->name) - 1; 488 MAX_BOARD_NAME - strlen(devpriv->name) - 1;
489 snprintf(buf, sizeof(buf), "%d:%d ", dev->minor, 489 snprintf(buf, sizeof(buf), "%d:%d ", dev->minor,
490 bdev->subdev); 490 bdev->subdev);
491 buf[sizeof(buf) - 1] = 0; 491 buf[sizeof(buf) - 1] = 0;
492 strncat(devpriv->name, buf, left); 492 strncat(devpriv->name, buf, left);
493 } 493 }
494 494
495 } 495 }
496 } 496 }
497 497
498 if (!devpriv->nchans) { 498 if (!devpriv->nchans) {
499 ERROR("No channels found!\n"); 499 ERROR("No channels found!\n");
500 return 0; 500 return 0;
501 } 501 }
502 502
503 return 1; 503 return 1;
504 } 504 }
505 505
506 static void doDevUnconfig(struct comedi_device *dev) 506 static void doDevUnconfig(struct comedi_device *dev)
507 { 507 {
508 unsigned long devs_closed = 0; 508 unsigned long devs_closed = 0;
509 509
510 if (devpriv) { 510 if (devpriv) {
511 while (devpriv->ndevs-- && devpriv->devs) { 511 while (devpriv->ndevs-- && devpriv->devs) {
512 struct BondedDevice *bdev; 512 struct BondedDevice *bdev;
513 513
514 bdev = devpriv->devs[devpriv->ndevs]; 514 bdev = devpriv->devs[devpriv->ndevs];
515 if (!bdev) 515 if (!bdev)
516 continue; 516 continue;
517 if (!(devs_closed & (0x1 << bdev->minor))) { 517 if (!(devs_closed & (0x1 << bdev->minor))) {
518 comedi_close(bdev->dev); 518 comedi_close(bdev->dev);
519 devs_closed |= (0x1 << bdev->minor); 519 devs_closed |= (0x1 << bdev->minor);
520 } 520 }
521 kfree(bdev); 521 kfree(bdev);
522 } 522 }
523 kfree(devpriv->devs); 523 kfree(devpriv->devs);
524 devpriv->devs = NULL; 524 devpriv->devs = NULL;
525 kfree(devpriv); 525 kfree(devpriv);
526 dev->private = NULL; 526 dev->private = NULL;
527 } 527 }
528 } 528 }
529 529
530 static int __init init(void) 530 static int __init init(void)
531 { 531 {
532 return comedi_driver_register(&driver_bonding); 532 return comedi_driver_register(&driver_bonding);
533 } 533 }
534 534
535 static void __exit cleanup(void) 535 static void __exit cleanup(void)
536 { 536 {
537 comedi_driver_unregister(&driver_bonding); 537 comedi_driver_unregister(&driver_bonding);
538 } 538 }
539 539
540 module_init(init); 540 module_init(init);
drivers/staging/comedi/internal.h
1 /* 1 /*
2 * various internal comedi functions 2 * various internal comedi functions
3 */ 3 */
4 int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg); 4 int do_rangeinfo_ioctl(struct comedi_device *dev,
5 struct comedi_rangeinfo __user *arg);
5 int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, 6 int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
6 struct comedi_insn *insn, unsigned int *data); 7 struct comedi_insn *insn, unsigned int *data);
7 int comedi_alloc_board_minor(struct device *hardware_device); 8 int comedi_alloc_board_minor(struct device *hardware_device);
8 void comedi_free_board_minor(unsigned minor); 9 void comedi_free_board_minor(unsigned minor);
9 void comedi_reset_async_buf(struct comedi_async *async); 10 void comedi_reset_async_buf(struct comedi_async *async);
10 11
drivers/staging/comedi/range.c
1 /* 1 /*
2 module/range.c 2 module/range.c
3 comedi routines for voltage ranges 3 comedi routines for voltage ranges
4 4
5 COMEDI - Linux Control and Measurement Device Interface 5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> 6 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 21
22 */ 22 */
23 23
24 #include "comedidev.h"
25 #include <linux/uaccess.h> 24 #include <linux/uaccess.h>
25 #include "comedidev.h"
26 #include "internal.h"
26 27
27 const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} }; 28 const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
28 EXPORT_SYMBOL(range_bipolar10); 29 EXPORT_SYMBOL(range_bipolar10);
29 const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} }; 30 const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
30 EXPORT_SYMBOL(range_bipolar5); 31 EXPORT_SYMBOL(range_bipolar5);
31 const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} }; 32 const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
32 EXPORT_SYMBOL(range_bipolar2_5); 33 EXPORT_SYMBOL(range_bipolar2_5);
33 const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} }; 34 const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
34 EXPORT_SYMBOL(range_unipolar10); 35 EXPORT_SYMBOL(range_unipolar10);
35 const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} }; 36 const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
36 EXPORT_SYMBOL(range_unipolar5); 37 EXPORT_SYMBOL(range_unipolar5);
37 const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } }; 38 const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } };
38 EXPORT_SYMBOL(range_unknown); 39 EXPORT_SYMBOL(range_unknown);
39 40
40 /* 41 /*
41 COMEDI_RANGEINFO 42 COMEDI_RANGEINFO
42 range information ioctl 43 range information ioctl
43 44
44 arg: 45 arg:
45 pointer to rangeinfo structure 46 pointer to rangeinfo structure
46 47
47 reads: 48 reads:
48 range info structure 49 range info structure
49 50
50 writes: 51 writes:
51 n struct comedi_krange structures to rangeinfo->range_ptr 52 n struct comedi_krange structures to rangeinfo->range_ptr
52 */ 53 */
53 int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg) 54 int do_rangeinfo_ioctl(struct comedi_device *dev,
55 struct comedi_rangeinfo __user *arg)
54 { 56 {
55 struct comedi_rangeinfo it; 57 struct comedi_rangeinfo it;
56 int subd, chan; 58 int subd, chan;
57 const struct comedi_lrange *lr; 59 const struct comedi_lrange *lr;
58 struct comedi_subdevice *s; 60 struct comedi_subdevice *s;
59 61
60 if (copy_from_user(&it, arg, sizeof(struct comedi_rangeinfo))) 62 if (copy_from_user(&it, arg, sizeof(struct comedi_rangeinfo)))
61 return -EFAULT; 63 return -EFAULT;
62 subd = (it.range_type >> 24) & 0xf; 64 subd = (it.range_type >> 24) & 0xf;
63 chan = (it.range_type >> 16) & 0xff; 65 chan = (it.range_type >> 16) & 0xff;
64 66
65 if (!dev->attached) 67 if (!dev->attached)
66 return -EINVAL; 68 return -EINVAL;
67 if (subd >= dev->n_subdevices) 69 if (subd >= dev->n_subdevices)
68 return -EINVAL; 70 return -EINVAL;
69 s = dev->subdevices + subd; 71 s = dev->subdevices + subd;
70 if (s->range_table) { 72 if (s->range_table) {
71 lr = s->range_table; 73 lr = s->range_table;
72 } else if (s->range_table_list) { 74 } else if (s->range_table_list) {
73 if (chan >= s->n_chan) 75 if (chan >= s->n_chan)
74 return -EINVAL; 76 return -EINVAL;
75 lr = s->range_table_list[chan]; 77 lr = s->range_table_list[chan];
76 } else { 78 } else {
77 return -EINVAL; 79 return -EINVAL;
78 } 80 }
79 81
80 if (RANGE_LENGTH(it.range_type) != lr->length) { 82 if (RANGE_LENGTH(it.range_type) != lr->length) {
81 DPRINTK("wrong length %d should be %d (0x%08x)\n", 83 DPRINTK("wrong length %d should be %d (0x%08x)\n",
82 RANGE_LENGTH(it.range_type), lr->length, it.range_type); 84 RANGE_LENGTH(it.range_type), lr->length, it.range_type);
83 return -EINVAL; 85 return -EINVAL;
84 } 86 }
85 87
86 if (copy_to_user(it.range_ptr, lr->range, 88 if (copy_to_user(it.range_ptr, lr->range,
87 sizeof(struct comedi_krange) * lr->length)) 89 sizeof(struct comedi_krange) * lr->length))
88 return -EFAULT; 90 return -EFAULT;
89 91
90 return 0; 92 return 0;
91 } 93 }
92 94
93 static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) 95 static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec)
94 { 96 {
95 unsigned int aref; 97 unsigned int aref;
96 98
97 /* disable reporting invalid arefs... maybe someday */ 99 /* disable reporting invalid arefs... maybe someday */
98 return 0; 100 return 0;
99 101
100 aref = CR_AREF(chanspec); 102 aref = CR_AREF(chanspec);
101 switch (aref) { 103 switch (aref) {
102 case AREF_DIFF: 104 case AREF_DIFF:
103 if (s->subdev_flags & SDF_DIFF) 105 if (s->subdev_flags & SDF_DIFF)
104 return 0; 106 return 0;
105 break; 107 break;
106 case AREF_COMMON: 108 case AREF_COMMON:
107 if (s->subdev_flags & SDF_COMMON) 109 if (s->subdev_flags & SDF_COMMON)
108 return 0; 110 return 0;
109 break; 111 break;
110 case AREF_GROUND: 112 case AREF_GROUND:
111 if (s->subdev_flags & SDF_GROUND) 113 if (s->subdev_flags & SDF_GROUND)
112 return 0; 114 return 0;
113 break; 115 break;
114 case AREF_OTHER: 116 case AREF_OTHER:
115 if (s->subdev_flags & SDF_OTHER) 117 if (s->subdev_flags & SDF_OTHER)
116 return 0; 118 return 0;
117 break; 119 break;
118 default: 120 default:
119 break; 121 break;
120 } 122 }
121 DPRINTK("subdevice does not support aref %i", aref); 123 DPRINTK("subdevice does not support aref %i", aref);
122 return 1; 124 return 1;
123 } 125 }
124 126
125 /* 127 /*
126 This function checks each element in a channel/gain list to make 128 This function checks each element in a channel/gain list to make
127 make sure it is valid. 129 make sure it is valid.
128 */ 130 */
129 int comedi_check_chanlist(struct comedi_subdevice *s, int n, 131 int comedi_check_chanlist(struct comedi_subdevice *s, int n,
130 unsigned int *chanlist) 132 unsigned int *chanlist)
131 { 133 {
132 int i; 134 int i;
133 int chan; 135 int chan;
134 136
135 if (s->range_table) { 137 if (s->range_table) {
136 for (i = 0; i < n; i++) 138 for (i = 0; i < n; i++)
137 if (CR_CHAN(chanlist[i]) >= s->n_chan || 139 if (CR_CHAN(chanlist[i]) >= s->n_chan ||
138 CR_RANGE(chanlist[i]) >= s->range_table->length 140 CR_RANGE(chanlist[i]) >= s->range_table->length
139 || aref_invalid(s, chanlist[i])) { 141 || aref_invalid(s, chanlist[i])) {
140 printk(KERN_ERR "bad chanlist[%d]=0x%08x " 142 printk(KERN_ERR "bad chanlist[%d]=0x%08x "
141 "in_chan=%d range length=%d\n", i, 143 "in_chan=%d range length=%d\n", i,
142 chanlist[i], s->n_chan, 144 chanlist[i], s->n_chan,
143 s->range_table->length); 145 s->range_table->length);
144 return -EINVAL; 146 return -EINVAL;
145 } 147 }
146 } else if (s->range_table_list) { 148 } else if (s->range_table_list) {
147 for (i = 0; i < n; i++) { 149 for (i = 0; i < n; i++) {
148 chan = CR_CHAN(chanlist[i]); 150 chan = CR_CHAN(chanlist[i]);
149 if (chan >= s->n_chan || 151 if (chan >= s->n_chan ||
150 CR_RANGE(chanlist[i]) >= 152 CR_RANGE(chanlist[i]) >=
151 s->range_table_list[chan]->length 153 s->range_table_list[chan]->length
152 || aref_invalid(s, chanlist[i])) { 154 || aref_invalid(s, chanlist[i])) {
153 printk(KERN_ERR "bad chanlist[%d]=0x%08x\n", 155 printk(KERN_ERR "bad chanlist[%d]=0x%08x\n",
154 i, chanlist[i]); 156 i, chanlist[i]);
155 return -EINVAL; 157 return -EINVAL;
156 } 158 }
157 } 159 }
158 } else { 160 } else {
159 printk(KERN_ERR "comedi: (bug) no range type list!\n"); 161 printk(KERN_ERR "comedi: (bug) no range type list!\n");
160 return -EINVAL; 162 return -EINVAL;
161 } 163 }
162 return 0; 164 return 0;
163 } 165 }
164 EXPORT_SYMBOL(comedi_check_chanlist); 166 EXPORT_SYMBOL(comedi_check_chanlist);