~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/staging/comedi/kcomedilib/kcomedilib_main.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    kcomedilib/kcomedilib.c
 
3
    a comedlib interface for kernel modules
 
4
 
 
5
    COMEDI - Linux Control and Measurement Device Interface
 
6
    Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
 
7
 
 
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
 
10
    the Free Software Foundation; either version 2 of the License, or
 
11
    (at your option) any later version.
 
12
 
 
13
    This program is distributed in the hope that it will be useful,
 
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
    GNU General Public License for more details.
 
17
 
 
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
 
20
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
21
 
 
22
*/
 
23
 
 
24
#define __NO_VERSION__
 
25
#include <linux/module.h>
 
26
 
 
27
#include <linux/errno.h>
 
28
#include <linux/kernel.h>
 
29
#include <linux/sched.h>
 
30
#include <linux/fcntl.h>
 
31
#include <linux/delay.h>
 
32
#include <linux/ioport.h>
 
33
#include <linux/mm.h>
 
34
#include <linux/io.h>
 
35
 
 
36
#include "../comedi.h"
 
37
#include "../comedilib.h"
 
38
#include "../comedidev.h"
 
39
 
 
40
MODULE_AUTHOR("David Schleef <ds@schleef.org>");
 
41
MODULE_DESCRIPTION("Comedi kernel library");
 
42
MODULE_LICENSE("GPL");
 
43
 
 
44
struct comedi_device *comedi_open(const char *filename)
 
45
{
 
46
        struct comedi_device_file_info *dev_file_info;
 
47
        struct comedi_device *dev;
 
48
        unsigned int minor;
 
49
 
 
50
        if (strncmp(filename, "/dev/comedi", 11) != 0)
 
51
                return NULL;
 
52
 
 
53
        minor = simple_strtoul(filename + 11, NULL, 0);
 
54
 
 
55
        if (minor >= COMEDI_NUM_BOARD_MINORS)
 
56
                return NULL;
 
57
 
 
58
        dev_file_info = comedi_get_device_file_info(minor);
 
59
        if (dev_file_info == NULL)
 
60
                return NULL;
 
61
        dev = dev_file_info->device;
 
62
 
 
63
        if (dev == NULL || !dev->attached)
 
64
                return NULL;
 
65
 
 
66
        if (!try_module_get(dev->driver->module))
 
67
                return NULL;
 
68
 
 
69
        return dev;
 
70
}
 
71
EXPORT_SYMBOL(comedi_open);
 
72
 
 
73
int comedi_close(struct comedi_device *d)
 
74
{
 
75
        struct comedi_device *dev = (struct comedi_device *)d;
 
76
 
 
77
        module_put(dev->driver->module);
 
78
 
 
79
        return 0;
 
80
}
 
81
EXPORT_SYMBOL(comedi_close);
 
82
 
 
83
static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
 
84
{
 
85
        struct comedi_subdevice *s;
 
86
        int ret = 0;
 
87
 
 
88
        /* a subdevice instruction */
 
89
        if (insn->subdev >= dev->n_subdevices) {
 
90
                ret = -EINVAL;
 
91
                goto error;
 
92
        }
 
93
        s = dev->subdevices + insn->subdev;
 
94
 
 
95
        if (s->type == COMEDI_SUBD_UNUSED) {
 
96
                printk(KERN_ERR "%d not useable subdevice\n", insn->subdev);
 
97
                ret = -EIO;
 
98
                goto error;
 
99
        }
 
100
 
 
101
        /* XXX check lock */
 
102
 
 
103
        ret = comedi_check_chanlist(s, 1, &insn->chanspec);
 
104
        if (ret < 0) {
 
105
                printk(KERN_ERR "bad chanspec\n");
 
106
                ret = -EINVAL;
 
107
                goto error;
 
108
        }
 
109
 
 
110
        if (s->busy) {
 
111
                ret = -EBUSY;
 
112
                goto error;
 
113
        }
 
114
        s->busy = dev;
 
115
 
 
116
        switch (insn->insn) {
 
117
        case INSN_BITS:
 
118
                ret = s->insn_bits(dev, s, insn, insn->data);
 
119
                break;
 
120
        case INSN_CONFIG:
 
121
                /* XXX should check instruction length */
 
122
                ret = s->insn_config(dev, s, insn, insn->data);
 
123
                break;
 
124
        default:
 
125
                ret = -EINVAL;
 
126
                break;
 
127
        }
 
128
 
 
129
        s->busy = NULL;
 
130
error:
 
131
 
 
132
        return ret;
 
133
}
 
134
 
 
135
int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
 
136
                      unsigned int chan, unsigned int io)
 
137
{
 
138
        struct comedi_insn insn;
 
139
 
 
140
        memset(&insn, 0, sizeof(insn));
 
141
        insn.insn = INSN_CONFIG;
 
142
        insn.n = 1;
 
143
        insn.data = &io;
 
144
        insn.subdev = subdev;
 
145
        insn.chanspec = CR_PACK(chan, 0, 0);
 
146
 
 
147
        return comedi_do_insn(dev, &insn);
 
148
}
 
149
EXPORT_SYMBOL(comedi_dio_config);
 
150
 
 
151
int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev,
 
152
                        unsigned int mask, unsigned int *bits)
 
153
{
 
154
        struct comedi_insn insn;
 
155
        unsigned int data[2];
 
156
        int ret;
 
157
 
 
158
        memset(&insn, 0, sizeof(insn));
 
159
        insn.insn = INSN_BITS;
 
160
        insn.n = 2;
 
161
        insn.data = data;
 
162
        insn.subdev = subdev;
 
163
 
 
164
        data[0] = mask;
 
165
        data[1] = *bits;
 
166
 
 
167
        ret = comedi_do_insn(dev, &insn);
 
168
 
 
169
        *bits = data[1];
 
170
 
 
171
        return ret;
 
172
}
 
173
EXPORT_SYMBOL(comedi_dio_bitfield);
 
174
 
 
175
int comedi_find_subdevice_by_type(struct comedi_device *dev, int type,
 
176
                                  unsigned int subd)
 
177
{
 
178
        if (subd > dev->n_subdevices)
 
179
                return -ENODEV;
 
180
 
 
181
        for (; subd < dev->n_subdevices; subd++) {
 
182
                if (dev->subdevices[subd].type == type)
 
183
                        return subd;
 
184
        }
 
185
        return -1;
 
186
}
 
187
EXPORT_SYMBOL(comedi_find_subdevice_by_type);
 
188
 
 
189
int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice)
 
190
{
 
191
        struct comedi_subdevice *s = dev->subdevices + subdevice;
 
192
 
 
193
        return s->n_chan;
 
194
}
 
195
EXPORT_SYMBOL(comedi_get_n_channels);