26 #define __NO_VERSION__
29 #include <linux/module.h>
30 #include <linux/errno.h>
31 #include <linux/kernel.h>
32 #include <linux/sched.h>
33 #include <linux/fcntl.h>
37 #include <linux/slab.h>
39 #include <linux/poll.h>
41 #include <linux/device.h>
46 #include <linux/stat.h>
57 #ifdef CONFIG_COMEDI_DEBUG
62 "enable comedi core and driver debugging if non-zero (default 0)"
69 "enable drivers to auto-configure comedi devices (default 1)");
71 static int comedi_num_legacy_minors;
74 "number of comedi minor devices to reserve for non-auto-configured devices (default 0)"
80 "default asynchronous buffer size in KiB (default "
84 = CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB;
87 "default maximum size of asynchronous buffer in KiB (default "
98 static int comedi_fasync(
int fd,
struct file *
file,
int on);
112 DPRINTK(
"subdevice is busy, cannot resize buffer\n");
116 DPRINTK(
"subdevice is mmapped, cannot resize buffer\n");
137 DPRINTK(
"comedi%i subd %d buffer resized to %i bytes\n",
149 unsigned int size = 0;
153 size = s->
async->max_bufsize / 1024;
161 const char *buf,
size_t count)
182 return err ? err :
count;
190 unsigned int size = 0;
194 size = s->
async->prealloc_bufsz / 1024;
202 const char *buf,
size_t count)
218 err = resize_async_buffer(info->
device, s, s->
async, size);
223 return err ? err :
count;
232 unsigned int size = 0;
236 size = s->
async->max_bufsize / 1024;
244 const char *buf,
size_t count)
265 return err ? err :
count;
273 unsigned int size = 0;
277 size = s->
async->prealloc_bufsz / 1024;
285 const char *buf,
size_t count)
301 err = resize_async_buffer(info->
device, s, s->
async, size);
306 return err ? err :
count;
311 show_max_read_buffer_kb, store_max_read_buffer_kb),
313 show_read_buffer_kb, store_read_buffer_kb),
315 show_max_write_buffer_kb, store_max_write_buffer_kb),
317 show_write_buffer_kb, store_write_buffer_kb),
339 unsigned char *aux_data =
NULL;
346 if (is_device_busy(dev))
351 module_put(driver_module);
361 if (comedi_aux_data(it.options, 0) &&
373 (
unsigned char __user *
374 )comedi_aux_data(it.options, 0), aux_len)) {
379 (
unsigned long)aux_data;
380 if (
sizeof(
void *) >
sizeof(
int)) {
381 bit_shift =
sizeof(
int) * 8;
383 ((
unsigned long)aux_data) >> bit_shift;
390 if (!try_module_get(dev->
driver->module)) {
434 DPRINTK(
"subdevice does not have async capability\n");
440 if (
bc.maximum_size) {
448 retval = resize_async_buffer(dev, s, async,
bc.size);
482 const unsigned minor = iminor(file->f_dentry->d_inode);
486 comedi_get_read_subdevice(dev_file_info);
488 comedi_get_write_subdevice(dev_file_info);
490 memset(&devinfo, 0,
sizeof(devinfo));
499 devinfo.read_subdevice = read_subdev - dev->
subdevices;
501 devinfo.read_subdevice = -1;
504 devinfo.write_subdevice = write_subdev - dev->
subdevices;
506 devinfo.write_subdevice = -1;
551 #define TIMER_nanosec 5
623 if (it.maxdata_list) {
627 s->
n_chan *
sizeof(
unsigned int)))
635 s->
n_chan *
sizeof(
unsigned int)))
644 for (i = 0; i < s->
n_chan; i++) {
647 x = (dev->
minor << 28) | (it.subdev << 24) | (i << 16) |
654 s->
n_chan *
sizeof(
unsigned int)))
697 DPRINTK(
"subdevice does not have async capability\n");
698 bi.buf_write_ptr = 0;
700 bi.buf_write_count = 0;
701 bi.buf_read_count = 0;
703 bi.bytes_written = 0;
708 bi.bytes_written = 0;
709 goto copyback_position;
721 do_become_nonbusy(dev, s);
745 unsigned int *
data,
void *file);
762 #define MAX_SAMPLES 256
792 DPRINTK(
"copy_from_user failed\n");
797 for (i = 0; i < insnlist.
n_insns; i++) {
798 if (insns[i].
n > MAX_SAMPLES) {
799 DPRINTK(
"number of samples too large\n");
805 insns[i].
n *
sizeof(
unsigned int))) {
806 DPRINTK(
"copy_from_user failed\n");
811 ret = parse_insn(dev, insns + i, data, file);
816 insns[i].
n *
sizeof(
unsigned int))) {
817 DPRINTK(
"copy_to_user failed\n");
886 pr_warn(
"comedi: No check for data length of config insn id %i is implemented.\n",
888 pr_warn(
"comedi: Add a check to %s in %s.\n",
890 pr_warn(
"comedi: Assuming n=%i is correct.\n", insn->
n);
897 unsigned int *data,
void *file)
906 switch (insn->
insn) {
918 data[1] = tv.tv_usec;
924 if (insn->
n != 1 || data[0] >= 100000) {
937 DPRINTK(
"%d not usable subdevice\n",
948 if (!s->
async->inttrig) {
953 ret = s->
async->inttrig(dev, s, data[0]);
964 unsigned int maxdata;
998 s->
busy = &parse_insn;
999 switch (insn->
insn) {
1007 for (i = 0; i < insn->
n; ++
i) {
1008 if (data[i] > maxdata) {
1010 DPRINTK(
"bad data value(s)\n");
1025 unsigned int orig_mask;
1027 orig_mask = data[0];
1038 data[0] = orig_mask;
1044 ret = check_insn_config_length(insn, data);
1079 unsigned int *data =
NULL;
1099 insn.
n *
sizeof(
unsigned int))) {
1104 ret = parse_insn(dev, &insn, data, file);
1110 insn.
n *
sizeof(
unsigned int))) {
1126 unsigned long flags;
1131 spin_unlock_irqrestore(&s->
spin_lock, flags);
1141 unsigned int __user *user_chanlist;
1148 user_chanlist = (
unsigned int __user *)
cmd.chanlist;
1151 DPRINTK(
"%d no such subdevice\n",
cmd.subdev);
1159 DPRINTK(
"%d not valid subdevice\n",
cmd.subdev);
1164 DPRINTK(
"subdevice %i does not support commands\n",
1171 DPRINTK(
"subdevice locked\n");
1184 DPRINTK(
"channel/gain list too long %u > %d\n",
1191 if (
cmd.chanlist_len < 1) {
1192 DPRINTK(
"channel/gain list too short %u < 1\n",
1201 async->
cmd.chanlist =
1203 if (!async->
cmd.chanlist) {
1204 DPRINTK(
"allocation failed\n");
1210 async->
cmd.chanlist_len *
sizeof(
int))) {
1211 DPRINTK(
"fault reading chanlist\n");
1218 async->
cmd.chanlist_len,
1219 async->
cmd.chanlist);
1228 DPRINTK(
"test returned %d\n", ret);
1231 cmd.chanlist = (
unsigned int __force *)user_chanlist;
1234 DPRINTK(
"fault writing cmd\n");
1256 comedi_set_subdevice_runflags(s, ~0,
SRF_USER | SRF_RUNNING);
1263 do_become_nonbusy(dev, s);
1290 unsigned int __user *user_chanlist;
1297 user_chanlist = (
unsigned int __user *)
cmd.chanlist;
1300 DPRINTK(
"%d no such subdevice\n",
cmd.subdev);
1306 DPRINTK(
"%d not valid subdevice\n",
cmd.subdev);
1311 DPRINTK(
"subdevice %i does not support commands\n",
1318 DPRINTK(
"channel/gain list too long %d > %d\n",
1329 DPRINTK(
"allocation failed\n");
1335 cmd.chanlist_len *
sizeof(
int))) {
1336 DPRINTK(
"fault reading chanlist\n");
1354 cmd.chanlist = (
unsigned int __force *)user_chanlist;
1382 static int do_lock_ioctl(
struct comedi_device *dev,
unsigned int arg,
1386 unsigned long flags;
1398 spin_unlock_irqrestore(&s->
spin_lock, flags);
1405 ret = s->lock_f(dev, s);
1427 static int do_unlock_ioctl(
struct comedi_device *dev,
unsigned int arg,
1442 if (s->
lock == file) {
1468 static int do_cancel_ioctl(
struct comedi_device *dev,
unsigned int arg,
1485 if (s->
busy != file)
1488 return do_cancel(dev, s);
1505 static int do_poll_ioctl(
struct comedi_device *dev,
unsigned int arg,
1520 if (s->
busy != file)
1524 return s->
poll(dev, s);
1529 static long comedi_unlocked_ioctl(
struct file *file,
unsigned int cmd,
1532 const unsigned minor = iminor(file->f_dentry->d_inode);
1540 dev = dev_file_info->
device;
1547 rc = do_devconfig_ioctl(dev,
1553 DPRINTK(
"no driver configured on /dev/comedi%i\n", dev->
minor);
1560 rc = do_bufconfig_ioctl(dev,
1568 rc = do_subdinfo_ioctl(dev,
1573 rc = do_chaninfo_ioctl(dev, (
void __user *)arg);
1579 rc = do_bufinfo_ioctl(dev,
1584 rc = do_lock_ioctl(dev, arg, file);
1587 rc = do_unlock_ioctl(dev, arg, file);
1590 rc = do_cancel_ioctl(dev, arg, file);
1593 rc = do_cmd_ioctl(dev, (
struct comedi_cmd __user *)arg, file);
1596 rc = do_cmdtest_ioctl(dev, (
struct comedi_cmd __user *)arg,
1600 rc = do_insnlist_ioctl(dev,
1605 rc = do_insn_ioctl(dev, (
struct comedi_insn __user *)arg,
1609 rc = do_poll_ioctl(dev, arg, file);
1628 do_become_nonbusy(dev, s);
1660 static struct vm_operations_struct comedi_vm_ops = {
1661 .open = comedi_vm_open,
1662 .close = comedi_vm_close,
1665 static int comedi_mmap(
struct file *file,
struct vm_area_struct *vma)
1667 const unsigned minor = iminor(file->f_dentry->d_inode);
1679 if (dev_file_info ==
NULL)
1681 dev = dev_file_info->
device;
1687 DPRINTK(
"no driver configured on comedi%i\n", dev->
minor);
1692 s = comedi_get_write_subdevice(dev_file_info);
1694 s = comedi_get_read_subdevice(dev_file_info);
1701 if (async ==
NULL) {
1707 DPRINTK(
"comedi: mmap() offset must be 0.\n");
1723 for (i = 0; i < n_pages; ++
i) {
1735 vma->
vm_ops = &comedi_vm_ops;
1746 static unsigned int comedi_poll(
struct file *file,
poll_table *
wait)
1748 unsigned int mask = 0;
1749 const unsigned minor = iminor(file->f_dentry->d_inode);
1756 if (dev_file_info ==
NULL)
1758 dev = dev_file_info->
device;
1764 DPRINTK(
"no driver configured on comedi%i\n", dev->
minor);
1770 read_subdev = comedi_get_read_subdevice(dev_file_info);
1772 poll_wait(file, &read_subdev->
async->wait_head, wait);
1773 if (!read_subdev->
busy
1780 write_subdev = comedi_get_write_subdevice(dev_file_info);
1782 poll_wait(file, &write_subdev->
async->wait_head, wait);
1784 write_subdev->
async->prealloc_bufsz);
1785 if (!write_subdev->
busy
1788 || comedi_buf_write_n_allocated(write_subdev->
async) >=
1798 static ssize_t comedi_write(
struct file *file,
const char __user *buf,
1803 int n,
m, count = 0, retval = 0;
1805 const unsigned minor = iminor(file->f_dentry->d_inode);
1810 if (dev_file_info ==
NULL)
1812 dev = dev_file_info->
device;
1817 DPRINTK(
"no driver configured on comedi%i\n", dev->
minor);
1822 s = comedi_get_write_subdevice(dev_file_info);
1837 if (s->
busy != file) {
1842 while (nbytes > 0 && !retval) {
1853 do_become_nonbusy(dev, s);
1864 if (m > comedi_buf_write_n_allocated(async))
1865 m = comedi_buf_write_n_allocated(async);
1875 if (signal_pending(
current)) {
1881 if (s->
busy != file) {
1906 return count ? count :
retval;
1909 static ssize_t comedi_read(
struct file *file,
char __user *buf,
size_t nbytes,
1914 int n,
m, count = 0, retval = 0;
1916 const unsigned minor = iminor(file->f_dentry->d_inode);
1921 if (dev_file_info ==
NULL)
1923 dev = dev_file_info->
device;
1928 DPRINTK(
"no driver configured on comedi%i\n", dev->
minor);
1933 s = comedi_get_read_subdevice(dev_file_info);
1947 if (s->
busy != file) {
1953 while (nbytes > 0 && !retval) {
1968 do_become_nonbusy(dev, s);
1982 if (signal_pending(
current)) {
1990 if (s->
busy != file) {
2014 do_become_nonbusy(dev, s);
2020 return count ? count :
retval;
2031 comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
2039 "BUG: (?) do_become_nonbusy called with async=NULL\n");
2045 static int comedi_open(
struct inode *
inode,
struct file *file)
2047 const unsigned minor = iminor(inode);
2051 dev_file_info ? dev_file_info->
device :
NULL;
2054 DPRINTK(
"invalid minor number\n");
2075 DPRINTK(
"in request module\n");
2093 DPRINTK(
"not attached and not CAP_NET_ADMIN\n");
2101 if (!try_module_get(dev->
driver->module)) {
2109 int rc = dev->
open(dev);
2111 module_put(dev->
driver->module);
2125 static int comedi_close(
struct inode *inode,
struct file *file)
2127 const unsigned minor = iminor(inode);
2134 if (dev_file_info ==
NULL)
2136 dev = dev_file_info->
device;
2146 if (s->
busy == file)
2148 if (s->
lock == file)
2157 module_put(dev->
driver->module);
2164 comedi_fasync(-1, file, 0);
2169 static int comedi_fasync(
int fd,
struct file *file,
int on)
2171 const unsigned minor = iminor(file->f_dentry->d_inode);
2176 if (dev_file_info ==
NULL)
2178 dev = dev_file_info->
device;
2187 .unlocked_ioctl = comedi_unlocked_ioctl,
2189 .open = comedi_open,
2190 .release = comedi_close,
2191 .read = comedi_read,
2192 .write = comedi_write,
2193 .mmap = comedi_mmap,
2194 .poll = comedi_poll,
2195 .fasync = comedi_fasync,
2199 static struct class *comedi_class;
2200 static struct cdev comedi_cdev;
2202 static void comedi_cleanup_legacy_minors(
void)
2206 for (i = 0; i < comedi_num_legacy_minors; i++)
2210 static int __init comedi_init(
void)
2217 if (comedi_num_legacy_minors < 0 ||
2219 pr_err(
"comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
2230 comedi_num_legacy_minors = 16;
2232 memset(comedi_file_info_table, 0,
2248 if (IS_ERR(comedi_class)) {
2249 pr_err(
"comedi: failed to create class\n");
2253 return PTR_ERR(comedi_class);
2256 comedi_class->
dev_attrs = comedi_dev_attrs;
2262 for (i = 0; i < comedi_num_legacy_minors; i++) {
2266 comedi_cleanup_legacy_minors();
2277 static void __exit comedi_cleanup(
void)
2281 comedi_cleanup_legacy_minors();
2283 BUG_ON(comedi_file_info_table[i]);
2289 comedi_proc_cleanup();
2304 unsigned runflags = 0;
2305 unsigned runflags_mask = 0;
2323 if (runflags_mask) {
2325 comedi_set_subdevice_runflags(s, runflags_mask, runflags);
2340 s->
async->events = 0;
2346 unsigned long flags;
2351 spin_unlock_irqrestore(&s->
spin_lock, flags);
2383 static void comedi_device_cleanup(
struct comedi_device *dev)
2408 comedi_device_init(info->
device);
2409 spin_lock(&comedi_file_info_table_lock);
2411 if (comedi_file_info_table[i] ==
NULL) {
2412 comedi_file_info_table[
i] =
info;
2416 spin_unlock(&comedi_file_info_table_lock);
2417 if (i == COMEDI_NUM_BOARD_MINORS) {
2418 comedi_device_cleanup(info->
device);
2421 pr_err(
"comedi: error: ran out of minor numbers for board device files.\n");
2428 info->
device->class_dev = csdev;
2439 spin_lock(&comedi_file_info_table_lock);
2440 info = comedi_file_info_table[minor];
2441 comedi_file_info_table[minor] =
NULL;
2442 spin_unlock(&comedi_file_info_table_lock);
2451 comedi_device_cleanup(dev);
2464 spin_lock(&comedi_file_info_table_lock);
2465 info = comedi_file_info_table[minor];
2467 spin_unlock(&comedi_file_info_table_lock);
2470 spin_unlock(&comedi_file_info_table_lock);
2488 spin_lock(&comedi_file_info_table_lock);
2490 if (comedi_file_info_table[i] ==
NULL) {
2491 comedi_file_info_table[
i] =
info;
2495 spin_unlock(&comedi_file_info_table_lock);
2496 if (i == COMEDI_NUM_MINORS) {
2498 pr_err(
"comedi: error: ran out of minor numbers for board device files.\n");
2524 spin_lock(&comedi_file_info_table_lock);
2525 info = comedi_file_info_table[s->
minor];
2526 comedi_file_info_table[s->
minor] =
NULL;
2527 spin_unlock(&comedi_file_info_table_lock);
2540 BUG_ON(minor >= COMEDI_NUM_MINORS);
2541 spin_lock(&comedi_file_info_table_lock);
2542 info = comedi_file_info_table[minor];
2543 spin_unlock(&comedi_file_info_table_lock);