aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/comedi_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r--drivers/staging/comedi/comedi_fops.c528
1 files changed, 263 insertions, 265 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index f44566416f5..018c964396d 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -45,10 +45,10 @@
45#include "comedidev.h" 45#include "comedidev.h"
46#include <linux/cdev.h> 46#include <linux/cdev.h>
47 47
48#include <asm/io.h> 48#include <linux/io.h>
49#include <asm/uaccess.h> 49#include <linux/uaccess.h>
50 50
51//#include "kvmem.h" 51/* #include "kvmem.h" */
52 52
53MODULE_AUTHOR("http://www.comedi.org"); 53MODULE_AUTHOR("http://www.comedi.org");
54MODULE_DESCRIPTION("Comedi core module"); 54MODULE_DESCRIPTION("Comedi core module");
@@ -60,42 +60,44 @@ module_param(comedi_debug, int, 0644);
60#endif 60#endif
61 61
62static DEFINE_SPINLOCK(comedi_file_info_table_lock); 62static DEFINE_SPINLOCK(comedi_file_info_table_lock);
63static struct comedi_device_file_info* comedi_file_info_table[COMEDI_NUM_MINORS]; 63static struct comedi_device_file_info
64 64 *comedi_file_info_table[COMEDI_NUM_MINORS];
65static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg); 65
66static int do_bufconfig_ioctl(comedi_device * dev, void *arg); 66static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg);
67static int do_devinfo_ioctl(comedi_device * dev, comedi_devinfo * arg, 67static int do_bufconfig_ioctl(comedi_device *dev, void *arg);
68 struct file *file); 68static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
69static int do_subdinfo_ioctl(comedi_device * dev, comedi_subdinfo * arg, 69 struct file *file);
70 void *file); 70static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
71static int do_chaninfo_ioctl(comedi_device * dev, comedi_chaninfo * arg); 71 void *file);
72static int do_bufinfo_ioctl(comedi_device * dev, void *arg); 72static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg);
73static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file); 73static int do_bufinfo_ioctl(comedi_device *dev, void *arg);
74static int do_lock_ioctl(comedi_device * dev, unsigned int arg, void *file); 74static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file);
75static int do_unlock_ioctl(comedi_device * dev, unsigned int arg, void *file); 75static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file);
76static int do_cancel_ioctl(comedi_device * dev, unsigned int arg, void *file); 76static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file);
77static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file); 77static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file);
78static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file); 78static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file);
79static int do_insn_ioctl(comedi_device * dev, void *arg, void *file); 79static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file);
80static int do_poll_ioctl(comedi_device * dev, unsigned int subd, void *file); 80static int do_insn_ioctl(comedi_device *dev, void *arg, void *file);
81 81static int do_poll_ioctl(comedi_device *dev, unsigned int subd, void *file);
82void do_become_nonbusy(comedi_device * dev, comedi_subdevice * s); 82
83static int do_cancel(comedi_device * dev, comedi_subdevice * s); 83extern void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
84static int do_cancel(comedi_device *dev, comedi_subdevice *s);
84 85
85static int comedi_fasync(int fd, struct file *file, int on); 86static int comedi_fasync(int fd, struct file *file, int on);
86 87
87static int is_device_busy(comedi_device * dev); 88static int is_device_busy(comedi_device *dev);
88 89
89#ifdef HAVE_UNLOCKED_IOCTL 90#ifdef HAVE_UNLOCKED_IOCTL
90static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, 91static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
91 unsigned long arg) 92 unsigned long arg)
92#else 93#else
93static int comedi_ioctl(struct inode *inode, struct file *file, 94static int comedi_ioctl(struct inode *inode, struct file *file,
94 unsigned int cmd, unsigned long arg) 95 unsigned int cmd, unsigned long arg)
95#endif 96#endif
96{ 97{
97 const unsigned minor = iminor(file->f_dentry->d_inode); 98 const unsigned minor = iminor(file->f_dentry->d_inode);
98 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 99 struct comedi_device_file_info *dev_file_info =
100 comedi_get_device_file_info(minor);
99 comedi_device *dev = dev_file_info->device; 101 comedi_device *dev = dev_file_info->device;
100 int rc; 102 int rc;
101 103
@@ -162,7 +164,7 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
162 break; 164 break;
163 } 165 }
164 166
165 done: 167done:
166 mutex_unlock(&dev->mutex); 168 mutex_unlock(&dev->mutex);
167 return rc; 169 return rc;
168} 170}
@@ -180,7 +182,7 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
180 writes: 182 writes:
181 none 183 none
182*/ 184*/
183static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg) 185static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
184{ 186{
185 comedi_devconfig it; 187 comedi_devconfig it;
186 int ret; 188 int ret;
@@ -193,8 +195,7 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
193 if (arg == NULL) { 195 if (arg == NULL) {
194 if (is_device_busy(dev)) 196 if (is_device_busy(dev))
195 return -EBUSY; 197 return -EBUSY;
196 if(dev->attached) 198 if (dev->attached) {
197 {
198 struct module *driver_module = dev->driver->module; 199 struct module *driver_module = dev->driver->module;
199 comedi_device_detach(dev); 200 comedi_device_detach(dev);
200 module_put(driver_module); 201 module_put(driver_module);
@@ -208,7 +209,7 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
208 it.board_name[COMEDI_NAMELEN - 1] = 0; 209 it.board_name[COMEDI_NAMELEN - 1] = 0;
209 210
210 if (comedi_aux_data(it.options, 0) && 211 if (comedi_aux_data(it.options, 0) &&
211 it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { 212 it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
212 int bit_shift; 213 int bit_shift;
213 aux_len = it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; 214 aux_len = it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
214 if (aux_len < 0) 215 if (aux_len < 0)
@@ -219,24 +220,23 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
219 return -ENOMEM; 220 return -ENOMEM;
220 221
221 if (copy_from_user(aux_data, 222 if (copy_from_user(aux_data,
222 comedi_aux_data(it.options, 0), aux_len)) { 223 comedi_aux_data(it.options, 0), aux_len)) {
223 vfree(aux_data); 224 vfree(aux_data);
224 return -EFAULT; 225 return -EFAULT;
225 } 226 }
226 it.options[COMEDI_DEVCONF_AUX_DATA_LO] = 227 it.options[COMEDI_DEVCONF_AUX_DATA_LO] =
227 (unsigned long)aux_data; 228 (unsigned long)aux_data;
228 if (sizeof(void *) > sizeof(int)) { 229 if (sizeof(void *) > sizeof(int)) {
229 bit_shift = sizeof(int) * 8; 230 bit_shift = sizeof(int) * 8;
230 it.options[COMEDI_DEVCONF_AUX_DATA_HI] = 231 it.options[COMEDI_DEVCONF_AUX_DATA_HI] =
231 ((unsigned long)aux_data) >> bit_shift; 232 ((unsigned long)aux_data) >> bit_shift;
232 } else 233 } else
233 it.options[COMEDI_DEVCONF_AUX_DATA_HI] = 0; 234 it.options[COMEDI_DEVCONF_AUX_DATA_HI] = 0;
234 } 235 }
235 236
236 ret = comedi_device_attach(dev, &it); 237 ret = comedi_device_attach(dev, &it);
237 if(ret == 0) 238 if (ret == 0) {
238 { 239 if (!try_module_get(dev->driver->module)) {
239 if(!try_module_get(dev->driver->module)) {
240 comedi_device_detach(dev); 240 comedi_device_detach(dev);
241 return -ENOSYS; 241 return -ENOSYS;
242 } 242 }
@@ -262,7 +262,7 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
262 modified bufconfig at arg 262 modified bufconfig at arg
263 263
264*/ 264*/
265static int do_bufconfig_ioctl(comedi_device * dev, void *arg) 265static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
266{ 266{
267 comedi_bufconfig bc; 267 comedi_bufconfig bc;
268 comedi_async *async; 268 comedi_async *async;
@@ -329,7 +329,7 @@ static int do_bufconfig_ioctl(comedi_device * dev, void *arg)
329 bc.size = async->prealloc_bufsz; 329 bc.size = async->prealloc_bufsz;
330 bc.maximum_size = async->max_bufsize; 330 bc.maximum_size = async->max_bufsize;
331 331
332 copyback: 332copyback:
333 if (copy_to_user(arg, &bc, sizeof(comedi_bufconfig))) 333 if (copy_to_user(arg, &bc, sizeof(comedi_bufconfig)))
334 return -EFAULT; 334 return -EFAULT;
335 335
@@ -350,14 +350,17 @@ static int do_bufconfig_ioctl(comedi_device * dev, void *arg)
350 devinfo structure 350 devinfo structure
351 351
352*/ 352*/
353static int do_devinfo_ioctl(comedi_device * dev, comedi_devinfo * arg, 353static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
354 struct file *file) 354 struct file *file)
355{ 355{
356 comedi_devinfo devinfo; 356 comedi_devinfo devinfo;
357 const unsigned minor = iminor(file->f_dentry->d_inode); 357 const unsigned minor = iminor(file->f_dentry->d_inode);
358 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 358 struct comedi_device_file_info *dev_file_info =
359 comedi_subdevice *read_subdev = comedi_get_read_subdevice(dev_file_info); 359 comedi_get_device_file_info(minor);
360 comedi_subdevice *write_subdev = comedi_get_write_subdevice(dev_file_info); 360 comedi_subdevice *read_subdev =
361 comedi_get_read_subdevice(dev_file_info);
362 comedi_subdevice *write_subdev =
363 comedi_get_write_subdevice(dev_file_info);
361 364
362 memset(&devinfo, 0, sizeof(devinfo)); 365 memset(&devinfo, 0, sizeof(devinfo));
363 366
@@ -367,16 +370,15 @@ static int do_devinfo_ioctl(comedi_device * dev, comedi_devinfo * arg,
367 memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); 370 memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
368 memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); 371 memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
369 372
370 if (read_subdev) { 373 if (read_subdev)
371 devinfo.read_subdevice = read_subdev - dev->subdevices; 374 devinfo.read_subdevice = read_subdev - dev->subdevices;
372 } else { 375 else
373 devinfo.read_subdevice = -1; 376 devinfo.read_subdevice = -1;
374 } 377
375 if (write_subdev) { 378 if (write_subdev)
376 devinfo.write_subdevice = write_subdev - dev->subdevices; 379 devinfo.write_subdevice = write_subdev - dev->subdevices;
377 } else { 380 else
378 devinfo.write_subdevice = -1; 381 devinfo.write_subdevice = -1;
379 }
380 382
381 if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo))) 383 if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo)))
382 return -EFAULT; 384 return -EFAULT;
@@ -398,8 +400,8 @@ static int do_devinfo_ioctl(comedi_device * dev, comedi_devinfo * arg,
398 array of subdevice info structures at arg 400 array of subdevice info structures at arg
399 401
400*/ 402*/
401static int do_subdinfo_ioctl(comedi_device * dev, comedi_subdinfo * arg, 403static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
402 void *file) 404 void *file)
403{ 405{
404 int ret, i; 406 int ret, i;
405 comedi_subdinfo *tmp, *us; 407 comedi_subdinfo *tmp, *us;
@@ -425,8 +427,7 @@ static int do_subdinfo_ioctl(comedi_device * dev, comedi_subdinfo * arg,
425 us->maxdata = s->maxdata; 427 us->maxdata = s->maxdata;
426 if (s->range_table) { 428 if (s->range_table) {
427 us->range_type = 429 us->range_type =
428 (i << 24) | (0 << 16) | (s-> 430 (i << 24) | (0 << 16) | (s->range_table->length);
429 range_table->length);
430 } else { 431 } else {
431 us->range_type = 0; /* XXX */ 432 us->range_type = 0; /* XXX */
432 } 433 }
@@ -458,7 +459,7 @@ static int do_subdinfo_ioctl(comedi_device * dev, comedi_subdinfo * arg,
458 } 459 }
459 460
460 ret = copy_to_user(arg, tmp, 461 ret = copy_to_user(arg, tmp,
461 dev->n_subdevices * sizeof(comedi_subdinfo)); 462 dev->n_subdevices * sizeof(comedi_subdinfo));
462 463
463 kfree(tmp); 464 kfree(tmp);
464 465
@@ -479,7 +480,7 @@ static int do_subdinfo_ioctl(comedi_device * dev, comedi_subdinfo * arg,
479 arrays at elements of chaninfo structure 480 arrays at elements of chaninfo structure
480 481
481*/ 482*/
482static int do_chaninfo_ioctl(comedi_device * dev, comedi_chaninfo * arg) 483static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
483{ 484{
484 comedi_subdevice *s; 485 comedi_subdevice *s;
485 comedi_chaninfo it; 486 comedi_chaninfo it;
@@ -495,7 +496,7 @@ static int do_chaninfo_ioctl(comedi_device * dev, comedi_chaninfo * arg)
495 if (s->maxdata || !s->maxdata_list) 496 if (s->maxdata || !s->maxdata_list)
496 return -EINVAL; 497 return -EINVAL;
497 if (copy_to_user(it.maxdata_list, s->maxdata_list, 498 if (copy_to_user(it.maxdata_list, s->maxdata_list,
498 s->n_chan * sizeof(lsampl_t))) 499 s->n_chan * sizeof(lsampl_t)))
499 return -EFAULT; 500 return -EFAULT;
500 } 501 }
501 502
@@ -503,7 +504,7 @@ static int do_chaninfo_ioctl(comedi_device * dev, comedi_chaninfo * arg)
503 if (!s->flaglist) 504 if (!s->flaglist)
504 return -EINVAL; 505 return -EINVAL;
505 if (copy_to_user(it.flaglist, s->flaglist, 506 if (copy_to_user(it.flaglist, s->flaglist,
506 s->n_chan * sizeof(unsigned int))) 507 s->n_chan * sizeof(unsigned int)))
507 return -EFAULT; 508 return -EFAULT;
508 } 509 }
509 510
@@ -516,11 +517,14 @@ static int do_chaninfo_ioctl(comedi_device * dev, comedi_chaninfo * arg)
516 int x; 517 int x;
517 518
518 x = (dev->minor << 28) | (it.subdev << 24) | (i << 16) | 519 x = (dev->minor << 28) | (it.subdev << 24) | (i << 16) |
519 (s->range_table_list[i]->length); 520 (s->range_table_list[i]->length);
520 put_user(x, it.rangelist + i); 521 put_user(x, it.rangelist + i);
521 } 522 }
522 //if(copy_to_user(it.rangelist,s->range_type_list,s->n_chan*sizeof(unsigned int))) 523#if 0
523 // return -EFAULT; 524 if (copy_to_user(it.rangelist, s->range_type_list,
525 s->n_chan*sizeof(unsigned int)))
526 return -EFAULT;
527#endif
524 } 528 }
525 529
526 return 0; 530 return 0;
@@ -540,7 +544,7 @@ static int do_chaninfo_ioctl(comedi_device * dev, comedi_chaninfo * arg)
540 modified bufinfo at arg 544 modified bufinfo at arg
541 545
542 */ 546 */
543static int do_bufinfo_ioctl(comedi_device * dev, void *arg) 547static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
544{ 548{
545 comedi_bufinfo bi; 549 comedi_bufinfo bi;
546 comedi_subdevice *s; 550 comedi_subdevice *s;
@@ -569,15 +573,15 @@ static int do_bufinfo_ioctl(comedi_device * dev, void *arg)
569 comedi_buf_read_free(async, bi.bytes_read); 573 comedi_buf_read_free(async, bi.bytes_read);
570 574
571 if (!(comedi_get_subdevice_runflags(s) & (SRF_ERROR | 575 if (!(comedi_get_subdevice_runflags(s) & (SRF_ERROR |
572 SRF_RUNNING)) 576 SRF_RUNNING))
573 && async->buf_write_count == async->buf_read_count) { 577 && async->buf_write_count == async->buf_read_count) {
574 do_become_nonbusy(dev, s); 578 do_become_nonbusy(dev, s);
575 } 579 }
576 } 580 }
577 581
578 if (bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)) { 582 if (bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)) {
579 bi.bytes_written = 583 bi.bytes_written =
580 comedi_buf_write_alloc(async, bi.bytes_written); 584 comedi_buf_write_alloc(async, bi.bytes_written);
581 comedi_buf_write_free(async, bi.bytes_written); 585 comedi_buf_write_free(async, bi.bytes_written);
582 } 586 }
583 587
@@ -586,15 +590,15 @@ static int do_bufinfo_ioctl(comedi_device * dev, void *arg)
586 bi.buf_read_count = async->buf_read_count; 590 bi.buf_read_count = async->buf_read_count;
587 bi.buf_read_ptr = async->buf_read_ptr; 591 bi.buf_read_ptr = async->buf_read_ptr;
588 592
589 copyback: 593copyback:
590 if (copy_to_user(arg, &bi, sizeof(comedi_bufinfo))) 594 if (copy_to_user(arg, &bi, sizeof(comedi_bufinfo)))
591 return -EFAULT; 595 return -EFAULT;
592 596
593 return 0; 597 return 0;
594} 598}
595 599
596static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data, 600static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
597 void *file); 601 void *file);
598/* 602/*
599 * COMEDI_INSNLIST 603 * COMEDI_INSNLIST
600 * synchronous instructions 604 * synchronous instructions
@@ -612,7 +616,7 @@ static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data,
612 */ 616 */
613/* arbitrary limits */ 617/* arbitrary limits */
614#define MAX_SAMPLES 256 618#define MAX_SAMPLES 256
615static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file) 619static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
616{ 620{
617 comedi_insnlist insnlist; 621 comedi_insnlist insnlist;
618 comedi_insn *insns = NULL; 622 comedi_insn *insns = NULL;
@@ -638,7 +642,7 @@ static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file)
638 } 642 }
639 643
640 if (copy_from_user(insns, insnlist.insns, 644 if (copy_from_user(insns, insnlist.insns,
641 sizeof(comedi_insn) * insnlist.n_insns)) { 645 sizeof(comedi_insn) * insnlist.n_insns)) {
642 DPRINTK("copy_from_user failed\n"); 646 DPRINTK("copy_from_user failed\n");
643 ret = -EFAULT; 647 ret = -EFAULT;
644 goto error; 648 goto error;
@@ -652,7 +656,7 @@ static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file)
652 } 656 }
653 if (insns[i].insn & INSN_MASK_WRITE) { 657 if (insns[i].insn & INSN_MASK_WRITE) {
654 if (copy_from_user(data, insns[i].data, 658 if (copy_from_user(data, insns[i].data,
655 insns[i].n * sizeof(lsampl_t))) { 659 insns[i].n * sizeof(lsampl_t))) {
656 DPRINTK("copy_from_user failed\n"); 660 DPRINTK("copy_from_user failed\n");
657 ret = -EFAULT; 661 ret = -EFAULT;
658 goto error; 662 goto error;
@@ -663,7 +667,7 @@ static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file)
663 goto error; 667 goto error;
664 if (insns[i].insn & INSN_MASK_READ) { 668 if (insns[i].insn & INSN_MASK_READ) {
665 if (copy_to_user(insns[i].data, data, 669 if (copy_to_user(insns[i].data, data,
666 insns[i].n * sizeof(lsampl_t))) { 670 insns[i].n * sizeof(lsampl_t))) {
667 DPRINTK("copy_to_user failed\n"); 671 DPRINTK("copy_to_user failed\n");
668 ret = -EFAULT; 672 ret = -EFAULT;
669 goto error; 673 goto error;
@@ -673,20 +677,19 @@ static int do_insnlist_ioctl(comedi_device * dev, void *arg, void *file)
673 schedule(); 677 schedule();
674 } 678 }
675 679
676 error: 680error:
677 if (insns) 681 kfree(insns);
678 kfree(insns); 682 kfree(data);
679 if (data)
680 kfree(data);
681 683
682 if (ret < 0) 684 if (ret < 0)
683 return ret; 685 return ret;
684 return i; 686 return i;
685} 687}
686 688
687static int check_insn_config_length(comedi_insn * insn, lsampl_t * data) 689static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
688{ 690{
689 if(insn->n < 1) return -EINVAL; 691 if (insn->n < 1)
692 return -EINVAL;
690 693
691 switch (data[0]) { 694 switch (data[0]) {
692 case INSN_CONFIG_DIO_OUTPUT: 695 case INSN_CONFIG_DIO_OUTPUT:
@@ -730,21 +733,22 @@ static int check_insn_config_length(comedi_insn * insn, lsampl_t * data)
730 if (insn->n == 5) 733 if (insn->n == 5)
731 return 0; 734 return 0;
732 break; 735 break;
733 //by default we allow the insn since we don't have checks for all possible cases yet 736 /* by default we allow the insn since we don't have checks for
737 * all possible cases yet */
734 default: 738 default:
735 rt_printk 739 rt_printk("comedi: no check for data length of config insn id "
736 ("comedi: no check for data length of config insn id %i is implemented.\n" 740 "%i is implemented.\n"
737 " Add a check to %s in %s.\n" 741 " Add a check to %s in %s.\n"
738 " Assuming n=%i is correct.\n", data[0], __FUNCTION__, 742 " Assuming n=%i is correct.\n", data[0], __func__,
739 __FILE__, insn->n); 743 __FILE__, insn->n);
740 return 0; 744 return 0;
741 break; 745 break;
742 } 746 }
743 return -EINVAL; 747 return -EINVAL;
744} 748}
745 749
746static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data, 750static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
747 void *file) 751 void *file)
748{ 752{
749 comedi_subdevice *s; 753 comedi_subdevice *s;
750 int ret = 0; 754 int ret = 0;
@@ -833,7 +837,8 @@ static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data,
833 goto out; 837 goto out;
834 } 838 }
835 839
836 if ((ret = check_chanlist(s, 1, &insn->chanspec)) < 0) { 840 ret = check_chanlist(s, 1, &insn->chanspec);
841 if (ret < 0) {
837 ret = -EINVAL; 842 ret = -EINVAL;
838 DPRINTK("bad chanspec\n"); 843 DPRINTK("bad chanspec\n");
839 goto out; 844 goto out;
@@ -851,8 +856,8 @@ static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data,
851 break; 856 break;
852 case INSN_WRITE: 857 case INSN_WRITE:
853 maxdata = s->maxdata_list 858 maxdata = s->maxdata_list
854 ? s->maxdata_list[CR_CHAN(insn->chanspec)] 859 ? s->maxdata_list[CR_CHAN(insn->chanspec)]
855 : s->maxdata; 860 : s->maxdata;
856 for (i = 0; i < insn->n; ++i) { 861 for (i = 0; i < insn->n; ++i) {
857 if (data[i] > maxdata) { 862 if (data[i] > maxdata) {
858 ret = -EINVAL; 863 ret = -EINVAL;
@@ -884,7 +889,7 @@ static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data,
884 s->busy = NULL; 889 s->busy = NULL;
885 } 890 }
886 891
887 out: 892out:
888 return ret; 893 return ret;
889} 894}
890 895
@@ -902,7 +907,7 @@ static int parse_insn(comedi_device * dev, comedi_insn * insn, lsampl_t * data,
902 * writes: 907 * writes:
903 * data (for reads) 908 * data (for reads)
904 */ 909 */
905static int do_insn_ioctl(comedi_device * dev, void *arg, void *file) 910static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
906{ 911{
907 comedi_insn insn; 912 comedi_insn insn;
908 lsampl_t *data = NULL; 913 lsampl_t *data = NULL;
@@ -939,9 +944,8 @@ static int do_insn_ioctl(comedi_device * dev, void *arg, void *file)
939 } 944 }
940 ret = insn.n; 945 ret = insn.n;
941 946
942 error: 947error:
943 if (data) 948 kfree(data);
944 kfree(data);
945 949
946 return ret; 950 return ret;
947} 951}
@@ -961,7 +965,7 @@ static int do_insn_ioctl(comedi_device * dev, void *arg, void *file)
961 modified cmd structure at arg 965 modified cmd structure at arg
962 966
963*/ 967*/
964static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file) 968static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
965{ 969{
966 comedi_cmd user_cmd; 970 comedi_cmd user_cmd;
967 comedi_subdevice *s; 971 comedi_subdevice *s;
@@ -973,7 +977,7 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
973 DPRINTK("bad cmd address\n"); 977 DPRINTK("bad cmd address\n");
974 return -EFAULT; 978 return -EFAULT;
975 } 979 }
976 // save user's chanlist pointer so it can be restored later 980 /* save user's chanlist pointer so it can be restored later */
977 chanlist_saver = user_cmd.chanlist; 981 chanlist_saver = user_cmd.chanlist;
978 982
979 if (user_cmd.subdev >= dev->n_subdevices) { 983 if (user_cmd.subdev >= dev->n_subdevices) {
@@ -1024,13 +1028,12 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
1024 goto cleanup; 1028 goto cleanup;
1025 } 1029 }
1026 1030
1027 if (async->cmd.chanlist) 1031 kfree(async->cmd.chanlist);
1028 kfree(async->cmd.chanlist);
1029 async->cmd = user_cmd; 1032 async->cmd = user_cmd;
1030 async->cmd.data = NULL; 1033 async->cmd.data = NULL;
1031 /* load channel/gain list */ 1034 /* load channel/gain list */
1032 async->cmd.chanlist = 1035 async->cmd.chanlist =
1033 kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL); 1036 kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL);
1034 if (!async->cmd.chanlist) { 1037 if (!async->cmd.chanlist) {
1035 DPRINTK("allocation failed\n"); 1038 DPRINTK("allocation failed\n");
1036 ret = -ENOMEM; 1039 ret = -ENOMEM;
@@ -1038,15 +1041,15 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
1038 } 1041 }
1039 1042
1040 if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist, 1043 if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist,
1041 async->cmd.chanlist_len * sizeof(int))) { 1044 async->cmd.chanlist_len * sizeof(int))) {
1042 DPRINTK("fault reading chanlist\n"); 1045 DPRINTK("fault reading chanlist\n");
1043 ret = -EFAULT; 1046 ret = -EFAULT;
1044 goto cleanup; 1047 goto cleanup;
1045 } 1048 }
1046 1049
1047 /* make sure each element in channel/gain list is valid */ 1050 /* make sure each element in channel/gain list is valid */
1048 if ((ret = check_chanlist(s, async->cmd.chanlist_len, 1051 ret = check_chanlist(s, async->cmd.chanlist_len, async->cmd.chanlist);
1049 async->cmd.chanlist)) < 0) { 1052 if (ret < 0) {
1050 DPRINTK("bad chanlist\n"); 1053 DPRINTK("bad chanlist\n");
1051 goto cleanup; 1054 goto cleanup;
1052 } 1055 }
@@ -1056,7 +1059,7 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
1056 if (async->cmd.flags & TRIG_BOGUS || ret) { 1059 if (async->cmd.flags & TRIG_BOGUS || ret) {
1057 DPRINTK("test returned %d\n", ret); 1060 DPRINTK("test returned %d\n", ret);
1058 user_cmd = async->cmd; 1061 user_cmd = async->cmd;
1059 // restore chanlist pointer before copying back 1062 /* restore chanlist pointer before copying back */
1060 user_cmd.chanlist = chanlist_saver; 1063 user_cmd.chanlist = chanlist_saver;
1061 user_cmd.data = NULL; 1064 user_cmd.data = NULL;
1062 if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) { 1065 if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
@@ -1077,11 +1080,10 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
1077 comedi_reset_async_buf(async); 1080 comedi_reset_async_buf(async);
1078 1081
1079 async->cb_mask = 1082 async->cb_mask =
1080 COMEDI_CB_EOA | COMEDI_CB_BLOCK | COMEDI_CB_ERROR | 1083 COMEDI_CB_EOA | COMEDI_CB_BLOCK | COMEDI_CB_ERROR |
1081 COMEDI_CB_OVERFLOW; 1084 COMEDI_CB_OVERFLOW;
1082 if (async->cmd.flags & TRIG_WAKE_EOS) { 1085 if (async->cmd.flags & TRIG_WAKE_EOS)
1083 async->cb_mask |= COMEDI_CB_EOS; 1086 async->cb_mask |= COMEDI_CB_EOS;
1084 }
1085 1087
1086 comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING); 1088 comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING);
1087 1089
@@ -1096,7 +1098,7 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
1096 if (ret == 0) 1098 if (ret == 0)
1097 return 0; 1099 return 0;
1098 1100
1099 cleanup: 1101cleanup:
1100 do_become_nonbusy(dev, s); 1102 do_become_nonbusy(dev, s);
1101 1103
1102 return ret; 1104 return ret;
@@ -1117,7 +1119,7 @@ static int do_cmd_ioctl(comedi_device * dev, void *arg, void *file)
1117 modified cmd structure at arg 1119 modified cmd structure at arg
1118 1120
1119*/ 1121*/
1120static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file) 1122static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
1121{ 1123{
1122 comedi_cmd user_cmd; 1124 comedi_cmd user_cmd;
1123 comedi_subdevice *s; 1125 comedi_subdevice *s;
@@ -1129,7 +1131,7 @@ static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file)
1129 DPRINTK("bad cmd address\n"); 1131 DPRINTK("bad cmd address\n");
1130 return -EFAULT; 1132 return -EFAULT;
1131 } 1133 }
1132 // save user's chanlist pointer so it can be restored later 1134 /* save user's chanlist pointer so it can be restored later */
1133 chanlist_saver = user_cmd.chanlist; 1135 chanlist_saver = user_cmd.chanlist;
1134 1136
1135 if (user_cmd.subdev >= dev->n_subdevices) { 1137 if (user_cmd.subdev >= dev->n_subdevices) {
@@ -1160,8 +1162,7 @@ static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file)
1160 /* load channel/gain list */ 1162 /* load channel/gain list */
1161 if (user_cmd.chanlist) { 1163 if (user_cmd.chanlist) {
1162 chanlist = 1164 chanlist =
1163 kmalloc(user_cmd.chanlist_len * sizeof(int), 1165 kmalloc(user_cmd.chanlist_len * sizeof(int), GFP_KERNEL);
1164 GFP_KERNEL);
1165 if (!chanlist) { 1166 if (!chanlist) {
1166 DPRINTK("allocation failed\n"); 1167 DPRINTK("allocation failed\n");
1167 ret = -ENOMEM; 1168 ret = -ENOMEM;
@@ -1169,15 +1170,15 @@ static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file)
1169 } 1170 }
1170 1171
1171 if (copy_from_user(chanlist, user_cmd.chanlist, 1172 if (copy_from_user(chanlist, user_cmd.chanlist,
1172 user_cmd.chanlist_len * sizeof(int))) { 1173 user_cmd.chanlist_len * sizeof(int))) {
1173 DPRINTK("fault reading chanlist\n"); 1174 DPRINTK("fault reading chanlist\n");
1174 ret = -EFAULT; 1175 ret = -EFAULT;
1175 goto cleanup; 1176 goto cleanup;
1176 } 1177 }
1177 1178
1178 /* make sure each element in channel/gain list is valid */ 1179 /* make sure each element in channel/gain list is valid */
1179 if ((ret = check_chanlist(s, user_cmd.chanlist_len, 1180 ret = check_chanlist(s, user_cmd.chanlist_len, chanlist);
1180 chanlist)) < 0) { 1181 if (ret < 0) {
1181 DPRINTK("bad chanlist\n"); 1182 DPRINTK("bad chanlist\n");
1182 goto cleanup; 1183 goto cleanup;
1183 } 1184 }
@@ -1187,7 +1188,7 @@ static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file)
1187 1188
1188 ret = s->do_cmdtest(dev, s, &user_cmd); 1189 ret = s->do_cmdtest(dev, s, &user_cmd);
1189 1190
1190 // restore chanlist pointer before copying back 1191 /* restore chanlist pointer before copying back */
1191 user_cmd.chanlist = chanlist_saver; 1192 user_cmd.chanlist = chanlist_saver;
1192 1193
1193 if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) { 1194 if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
@@ -1195,9 +1196,8 @@ static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file)
1195 ret = -EFAULT; 1196 ret = -EFAULT;
1196 goto cleanup; 1197 goto cleanup;
1197 } 1198 }
1198 cleanup: 1199cleanup:
1199 if (chanlist) 1200 kfree(chanlist);
1200 kfree(chanlist);
1201 1201
1202 return ret; 1202 return ret;
1203} 1203}
@@ -1217,7 +1217,7 @@ static int do_cmdtest_ioctl(comedi_device * dev, void *arg, void *file)
1217 1217
1218*/ 1218*/
1219 1219
1220static int do_lock_ioctl(comedi_device * dev, unsigned int arg, void *file) 1220static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
1221{ 1221{
1222 int ret = 0; 1222 int ret = 0;
1223 unsigned long flags; 1223 unsigned long flags;
@@ -1228,11 +1228,10 @@ static int do_lock_ioctl(comedi_device * dev, unsigned int arg, void *file)
1228 s = dev->subdevices + arg; 1228 s = dev->subdevices + arg;
1229 1229
1230 comedi_spin_lock_irqsave(&s->spin_lock, flags); 1230 comedi_spin_lock_irqsave(&s->spin_lock, flags);
1231 if (s->busy || s->lock) { 1231 if (s->busy || s->lock)
1232 ret = -EBUSY; 1232 ret = -EBUSY;
1233 } else { 1233 else
1234 s->lock = file; 1234 s->lock = file;
1235 }
1236 comedi_spin_unlock_irqrestore(&s->spin_lock, flags); 1235 comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
1237 1236
1238 if (ret < 0) 1237 if (ret < 0)
@@ -1262,7 +1261,7 @@ static int do_lock_ioctl(comedi_device * dev, unsigned int arg, void *file)
1262 This function isn't protected by the semaphore, since 1261 This function isn't protected by the semaphore, since
1263 we already own the lock. 1262 we already own the lock.
1264*/ 1263*/
1265static int do_unlock_ioctl(comedi_device * dev, unsigned int arg, void *file) 1264static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
1266{ 1265{
1267 comedi_subdevice *s; 1266 comedi_subdevice *s;
1268 1267
@@ -1302,7 +1301,7 @@ static int do_unlock_ioctl(comedi_device * dev, unsigned int arg, void *file)
1302 nothing 1301 nothing
1303 1302
1304*/ 1303*/
1305static int do_cancel_ioctl(comedi_device * dev, unsigned int arg, void *file) 1304static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
1306{ 1305{
1307 comedi_subdevice *s; 1306 comedi_subdevice *s;
1308 1307
@@ -1338,7 +1337,7 @@ static int do_cancel_ioctl(comedi_device * dev, unsigned int arg, void *file)
1338 nothing 1337 nothing
1339 1338
1340*/ 1339*/
1341static int do_poll_ioctl(comedi_device * dev, unsigned int arg, void *file) 1340static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
1342{ 1341{
1343 comedi_subdevice *s; 1342 comedi_subdevice *s;
1344 1343
@@ -1361,7 +1360,7 @@ static int do_poll_ioctl(comedi_device * dev, unsigned int arg, void *file)
1361 return -EINVAL; 1360 return -EINVAL;
1362} 1361}
1363 1362
1364static int do_cancel(comedi_device * dev, comedi_subdevice * s) 1363static int do_cancel(comedi_device *dev, comedi_subdevice *s)
1365{ 1364{
1366 int ret = 0; 1365 int ret = 0;
1367 1366
@@ -1387,13 +1386,14 @@ void comedi_unmap(struct vm_area_struct *area)
1387} 1386}
1388 1387
1389static struct vm_operations_struct comedi_vm_ops = { 1388static struct vm_operations_struct comedi_vm_ops = {
1390 close:comedi_unmap, 1389 .close = comedi_unmap,
1391}; 1390};
1392 1391
1393static int comedi_mmap(struct file *file, struct vm_area_struct *vma) 1392static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
1394{ 1393{
1395 const unsigned minor = iminor(file->f_dentry->d_inode); 1394 const unsigned minor = iminor(file->f_dentry->d_inode);
1396 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1395 struct comedi_device_file_info *dev_file_info =
1396 comedi_get_device_file_info(minor);
1397 comedi_device *dev = dev_file_info->device; 1397 comedi_device *dev = dev_file_info->device;
1398 comedi_async *async = NULL; 1398 comedi_async *async = NULL;
1399 unsigned long start = vma->vm_start; 1399 unsigned long start = vma->vm_start;
@@ -1409,11 +1409,11 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
1409 retval = -ENODEV; 1409 retval = -ENODEV;
1410 goto done; 1410 goto done;
1411 } 1411 }
1412 if (vma->vm_flags & VM_WRITE) { 1412 if (vma->vm_flags & VM_WRITE)
1413 s = comedi_get_write_subdevice(dev_file_info); 1413 s = comedi_get_write_subdevice(dev_file_info);
1414 } else { 1414 else
1415 s = comedi_get_read_subdevice(dev_file_info); 1415 s = comedi_get_read_subdevice(dev_file_info);
1416 } 1416
1417 if (s == NULL) { 1417 if (s == NULL) {
1418 retval = -EINVAL; 1418 retval = -EINVAL;
1419 goto done; 1419 goto done;
@@ -1443,9 +1443,10 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
1443 n_pages = size >> PAGE_SHIFT; 1443 n_pages = size >> PAGE_SHIFT;
1444 for (i = 0; i < n_pages; ++i) { 1444 for (i = 0; i < n_pages; ++i) {
1445 if (remap_pfn_range(vma, start, 1445 if (remap_pfn_range(vma, start,
1446 page_to_pfn(virt_to_page(async-> 1446 page_to_pfn(virt_to_page(async->
1447 buf_page_list[i].virt_addr)), 1447 buf_page_list[i].
1448 PAGE_SIZE, PAGE_SHARED)) { 1448 virt_addr)),
1449 PAGE_SIZE, PAGE_SHARED)) {
1449 retval = -EAGAIN; 1450 retval = -EAGAIN;
1450 goto done; 1451 goto done;
1451 } 1452 }
@@ -1458,16 +1459,17 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
1458 async->mmap_count++; 1459 async->mmap_count++;
1459 1460
1460 retval = 0; 1461 retval = 0;
1461 done: 1462done:
1462 mutex_unlock(&dev->mutex); 1463 mutex_unlock(&dev->mutex);
1463 return retval; 1464 return retval;
1464} 1465}
1465 1466
1466static unsigned int comedi_poll(struct file *file, poll_table * wait) 1467static unsigned int comedi_poll(struct file *file, poll_table *wait)
1467{ 1468{
1468 unsigned int mask = 0; 1469 unsigned int mask = 0;
1469 const unsigned minor = iminor(file->f_dentry->d_inode); 1470 const unsigned minor = iminor(file->f_dentry->d_inode);
1470 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1471 struct comedi_device_file_info *dev_file_info =
1472 comedi_get_device_file_info(minor);
1471 comedi_device *dev = dev_file_info->device; 1473 comedi_device *dev = dev_file_info->device;
1472 comedi_subdevice *read_subdev; 1474 comedi_subdevice *read_subdev;
1473 comedi_subdevice *write_subdev; 1475 comedi_subdevice *write_subdev;
@@ -1484,21 +1486,22 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
1484 if (read_subdev) { 1486 if (read_subdev) {
1485 poll_wait(file, &read_subdev->async->wait_head, wait); 1487 poll_wait(file, &read_subdev->async->wait_head, wait);
1486 if (!read_subdev->busy 1488 if (!read_subdev->busy
1487 || comedi_buf_read_n_available(read_subdev->async) > 0 1489 || comedi_buf_read_n_available(read_subdev->async) > 0
1488 || !(comedi_get_subdevice_runflags(read_subdev) & 1490 || !(comedi_get_subdevice_runflags(read_subdev) &
1489 SRF_RUNNING)) { 1491 SRF_RUNNING)) {
1490 mask |= POLLIN | POLLRDNORM; 1492 mask |= POLLIN | POLLRDNORM;
1491 } 1493 }
1492 } 1494 }
1493 write_subdev = comedi_get_write_subdevice(dev_file_info); 1495 write_subdev = comedi_get_write_subdevice(dev_file_info);
1494 if (write_subdev) { 1496 if (write_subdev) {
1495 poll_wait(file, &write_subdev->async->wait_head, wait); 1497 poll_wait(file, &write_subdev->async->wait_head, wait);
1496 comedi_buf_write_alloc(write_subdev->async, write_subdev->async->prealloc_bufsz); 1498 comedi_buf_write_alloc(write_subdev->async,
1499 write_subdev->async->prealloc_bufsz);
1497 if (!write_subdev->busy 1500 if (!write_subdev->busy
1498 || !(comedi_get_subdevice_runflags(write_subdev) & 1501 || !(comedi_get_subdevice_runflags(write_subdev) &
1499 SRF_RUNNING) 1502 SRF_RUNNING)
1500 || comedi_buf_write_n_allocated(write_subdev->async) >= 1503 || comedi_buf_write_n_allocated(write_subdev->async) >=
1501 bytes_per_sample(write_subdev->async->subdevice)) { 1504 bytes_per_sample(write_subdev->async->subdevice)) {
1502 mask |= POLLOUT | POLLWRNORM; 1505 mask |= POLLOUT | POLLWRNORM;
1503 } 1506 }
1504 } 1507 }
@@ -1508,14 +1511,15 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
1508} 1511}
1509 1512
1510static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes, 1513static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
1511 loff_t * offset) 1514 loff_t *offset)
1512{ 1515{
1513 comedi_subdevice *s; 1516 comedi_subdevice *s;
1514 comedi_async *async; 1517 comedi_async *async;
1515 int n, m, count = 0, retval = 0; 1518 int n, m, count = 0, retval = 0;
1516 DECLARE_WAITQUEUE(wait, current); 1519 DECLARE_WAITQUEUE(wait, current);
1517 const unsigned minor = iminor(file->f_dentry->d_inode); 1520 const unsigned minor = iminor(file->f_dentry->d_inode);
1518 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1521 struct comedi_device_file_info *dev_file_info =
1522 comedi_get_device_file_info(minor);
1519 comedi_device *dev = dev_file_info->device; 1523 comedi_device *dev = dev_file_info->device;
1520 1524
1521 if (!dev->attached) { 1525 if (!dev->attached) {
@@ -1550,20 +1554,18 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
1550 n = nbytes; 1554 n = nbytes;
1551 1555
1552 m = n; 1556 m = n;
1553 if (async->buf_write_ptr + m > async->prealloc_bufsz) { 1557 if (async->buf_write_ptr + m > async->prealloc_bufsz)
1554 m = async->prealloc_bufsz - async->buf_write_ptr; 1558 m = async->prealloc_bufsz - async->buf_write_ptr;
1555 }
1556 comedi_buf_write_alloc(async, async->prealloc_bufsz); 1559 comedi_buf_write_alloc(async, async->prealloc_bufsz);
1557 if (m > comedi_buf_write_n_allocated(async)) { 1560 if (m > comedi_buf_write_n_allocated(async))
1558 m = comedi_buf_write_n_allocated(async); 1561 m = comedi_buf_write_n_allocated(async);
1559 }
1560 if (m < n) 1562 if (m < n)
1561 n = m; 1563 n = m;
1562 1564
1563 if (n == 0) { 1565 if (n == 0) {
1564 if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) { 1566 if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
1565 if (comedi_get_subdevice_runflags(s) & 1567 if (comedi_get_subdevice_runflags(s) &
1566 SRF_ERROR) { 1568 SRF_ERROR) {
1567 retval = -EPIPE; 1569 retval = -EPIPE;
1568 } else { 1570 } else {
1569 retval = 0; 1571 retval = 0;
@@ -1580,9 +1582,8 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
1580 break; 1582 break;
1581 } 1583 }
1582 schedule(); 1584 schedule();
1583 if (!s->busy) { 1585 if (!s->busy)
1584 break; 1586 break;
1585 }
1586 if (s->busy != file) { 1587 if (s->busy != file) {
1587 retval = -EACCES; 1588 retval = -EACCES;
1588 break; 1589 break;
@@ -1591,7 +1592,7 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
1591 } 1592 }
1592 1593
1593 m = copy_from_user(async->prealloc_buf + async->buf_write_ptr, 1594 m = copy_from_user(async->prealloc_buf + async->buf_write_ptr,
1594 buf, n); 1595 buf, n);
1595 if (m) { 1596 if (m) {
1596 n -= m; 1597 n -= m;
1597 retval = -EFAULT; 1598 retval = -EFAULT;
@@ -1608,18 +1609,19 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
1608 remove_wait_queue(&async->wait_head, &wait); 1609 remove_wait_queue(&async->wait_head, &wait);
1609 1610
1610done: 1611done:
1611 return (count ? count : retval); 1612 return count ? count : retval;
1612} 1613}
1613 1614
1614static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes, 1615static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
1615 loff_t * offset) 1616 loff_t *offset)
1616{ 1617{
1617 comedi_subdevice *s; 1618 comedi_subdevice *s;
1618 comedi_async *async; 1619 comedi_async *async;
1619 int n, m, count = 0, retval = 0; 1620 int n, m, count = 0, retval = 0;
1620 DECLARE_WAITQUEUE(wait, current); 1621 DECLARE_WAITQUEUE(wait, current);
1621 const unsigned minor = iminor(file->f_dentry->d_inode); 1622 const unsigned minor = iminor(file->f_dentry->d_inode);
1622 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1623 struct comedi_device_file_info *dev_file_info =
1624 comedi_get_device_file_info(minor);
1623 comedi_device *dev = dev_file_info->device; 1625 comedi_device *dev = dev_file_info->device;
1624 1626
1625 if (!dev->attached) { 1627 if (!dev->attached) {
@@ -1654,11 +1656,10 @@ static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
1654 n = nbytes; 1656 n = nbytes;
1655 1657
1656 m = comedi_buf_read_n_available(async); 1658 m = comedi_buf_read_n_available(async);
1657//printk("%d available\n",m); 1659 /* printk("%d available\n",m); */
1658 if (async->buf_read_ptr + m > async->prealloc_bufsz) { 1660 if (async->buf_read_ptr + m > async->prealloc_bufsz)
1659 m = async->prealloc_bufsz - async->buf_read_ptr; 1661 m = async->prealloc_bufsz - async->buf_read_ptr;
1660 } 1662 /* printk("%d contiguous\n",m); */
1661//printk("%d contiguous\n",m);
1662 if (m < n) 1663 if (m < n)
1663 n = m; 1664 n = m;
1664 1665
@@ -1666,7 +1667,7 @@ static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
1666 if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) { 1667 if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
1667 do_become_nonbusy(dev, s); 1668 do_become_nonbusy(dev, s);
1668 if (comedi_get_subdevice_runflags(s) & 1669 if (comedi_get_subdevice_runflags(s) &
1669 SRF_ERROR) { 1670 SRF_ERROR) {
1670 retval = -EPIPE; 1671 retval = -EPIPE;
1671 } else { 1672 } else {
1672 retval = 0; 1673 retval = 0;
@@ -1693,7 +1694,7 @@ static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
1693 continue; 1694 continue;
1694 } 1695 }
1695 m = copy_to_user(buf, async->prealloc_buf + 1696 m = copy_to_user(buf, async->prealloc_buf +
1696 async->buf_read_ptr, n); 1697 async->buf_read_ptr, n);
1697 if (m) { 1698 if (m) {
1698 n -= m; 1699 n -= m;
1699 retval = -EFAULT; 1700 retval = -EFAULT;
@@ -1709,20 +1710,20 @@ static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
1709 break; /* makes device work like a pipe */ 1710 break; /* makes device work like a pipe */
1710 } 1711 }
1711 if (!(comedi_get_subdevice_runflags(s) & (SRF_ERROR | SRF_RUNNING)) && 1712 if (!(comedi_get_subdevice_runflags(s) & (SRF_ERROR | SRF_RUNNING)) &&
1712 async->buf_read_count - async->buf_write_count == 0) { 1713 async->buf_read_count - async->buf_write_count == 0) {
1713 do_become_nonbusy(dev, s); 1714 do_become_nonbusy(dev, s);
1714 } 1715 }
1715 set_current_state(TASK_RUNNING); 1716 set_current_state(TASK_RUNNING);
1716 remove_wait_queue(&async->wait_head, &wait); 1717 remove_wait_queue(&async->wait_head, &wait);
1717 1718
1718done: 1719done:
1719 return (count ? count : retval); 1720 return count ? count : retval;
1720} 1721}
1721 1722
1722/* 1723/*
1723 This function restores a subdevice to an idle state. 1724 This function restores a subdevice to an idle state.
1724 */ 1725 */
1725void do_become_nonbusy(comedi_device * dev, comedi_subdevice * s) 1726void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
1726{ 1727{
1727 comedi_async *async = s->async; 1728 comedi_async *async = s->async;
1728 1729
@@ -1737,7 +1738,8 @@ void do_become_nonbusy(comedi_device * dev, comedi_subdevice * s)
1737 comedi_reset_async_buf(async); 1738 comedi_reset_async_buf(async);
1738 async->inttrig = NULL; 1739 async->inttrig = NULL;
1739 } else { 1740 } else {
1740 printk("BUG: (?) do_become_nonbusy called with async=0\n"); 1741 printk(KERN_ERR
1742 "BUG: (?) do_become_nonbusy called with async=0\n");
1741 } 1743 }
1742 1744
1743 s->busy = NULL; 1745 s->busy = NULL;
@@ -1747,7 +1749,8 @@ static int comedi_open(struct inode *inode, struct file *file)
1747{ 1749{
1748 char mod[32]; 1750 char mod[32];
1749 const unsigned minor = iminor(inode); 1751 const unsigned minor = iminor(inode);
1750 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1752 struct comedi_device_file_info *dev_file_info =
1753 comedi_get_device_file_info(minor);
1751 comedi_device *dev = dev_file_info->device; 1754 comedi_device *dev = dev_file_info->device;
1752 if (dev == NULL) { 1755 if (dev == NULL) {
1753 DPRINTK("invalid minor number\n"); 1756 DPRINTK("invalid minor number\n");
@@ -1805,9 +1808,8 @@ ok:
1805 } 1808 }
1806 } 1809 }
1807 1810
1808 if (dev->attached && dev->use_count == 0 && dev->open) { 1811 if (dev->attached && dev->use_count == 0 && dev->open)
1809 dev->open(dev); 1812 dev->open(dev);
1810 }
1811 1813
1812 dev->use_count++; 1814 dev->use_count++;
1813 1815
@@ -1819,7 +1821,8 @@ ok:
1819static int comedi_close(struct inode *inode, struct file *file) 1821static int comedi_close(struct inode *inode, struct file *file)
1820{ 1822{
1821 const unsigned minor = iminor(inode); 1823 const unsigned minor = iminor(inode);
1822 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1824 struct comedi_device_file_info *dev_file_info =
1825 comedi_get_device_file_info(minor);
1823 comedi_device *dev = dev_file_info->device; 1826 comedi_device *dev = dev_file_info->device;
1824 comedi_subdevice *s = NULL; 1827 comedi_subdevice *s = NULL;
1825 int i; 1828 int i;
@@ -1830,30 +1833,25 @@ static int comedi_close(struct inode *inode, struct file *file)
1830 for (i = 0; i < dev->n_subdevices; i++) { 1833 for (i = 0; i < dev->n_subdevices; i++) {
1831 s = dev->subdevices + i; 1834 s = dev->subdevices + i;
1832 1835
1833 if (s->busy == file) { 1836 if (s->busy == file)
1834 do_cancel(dev, s); 1837 do_cancel(dev, s);
1835 } 1838 if (s->lock == file)
1836 if (s->lock == file) {
1837 s->lock = NULL; 1839 s->lock = NULL;
1838 }
1839 } 1840 }
1840 } 1841 }
1841 if (dev->attached && dev->use_count == 1 && dev->close) { 1842 if (dev->attached && dev->use_count == 1 && dev->close)
1842 dev->close(dev); 1843 dev->close(dev);
1843 }
1844 1844
1845 module_put(THIS_MODULE); 1845 module_put(THIS_MODULE);
1846 if (dev->attached) { 1846 if (dev->attached)
1847 module_put(dev->driver->module); 1847 module_put(dev->driver->module);
1848 }
1849 1848
1850 dev->use_count--; 1849 dev->use_count--;
1851 1850
1852 mutex_unlock(&dev->mutex); 1851 mutex_unlock(&dev->mutex);
1853 1852
1854 if (file->f_flags & FASYNC) { 1853 if (file->f_flags & FASYNC)
1855 comedi_fasync(-1, file, 0); 1854 comedi_fasync(-1, file, 0);
1856 }
1857 1855
1858 return 0; 1856 return 0;
1859} 1857}
@@ -1861,40 +1859,42 @@ static int comedi_close(struct inode *inode, struct file *file)
1861static int comedi_fasync(int fd, struct file *file, int on) 1859static int comedi_fasync(int fd, struct file *file, int on)
1862{ 1860{
1863 const unsigned minor = iminor(file->f_dentry->d_inode); 1861 const unsigned minor = iminor(file->f_dentry->d_inode);
1864 struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(minor); 1862 struct comedi_device_file_info *dev_file_info =
1863 comedi_get_device_file_info(minor);
1864
1865 comedi_device *dev = dev_file_info->device; 1865 comedi_device *dev = dev_file_info->device;
1866 1866
1867 return fasync_helper(fd, file, on, &dev->async_queue); 1867 return fasync_helper(fd, file, on, &dev->async_queue);
1868} 1868}
1869 1869
1870const struct file_operations comedi_fops = { 1870const struct file_operations comedi_fops = {
1871 owner:THIS_MODULE, 1871 .owner = THIS_MODULE,
1872#ifdef HAVE_UNLOCKED_IOCTL 1872#ifdef HAVE_UNLOCKED_IOCTL
1873 unlocked_ioctl:comedi_unlocked_ioctl, 1873 .unlocked_ioctl = comedi_unlocked_ioctl,
1874#else 1874#else
1875 ioctl:comedi_ioctl, 1875 .ioctl = comedi_ioctl,
1876#endif 1876#endif
1877#ifdef HAVE_COMPAT_IOCTL 1877#ifdef HAVE_COMPAT_IOCTL
1878 compat_ioctl:comedi_compat_ioctl, 1878 .compat_ioctl = comedi_compat_ioctl,
1879#endif 1879#endif
1880 open:comedi_open, 1880 .open = comedi_open,
1881 release:comedi_close, 1881 .release = comedi_close,
1882 read:comedi_read, 1882 .read = comedi_read,
1883 write:comedi_write, 1883 .write = comedi_write,
1884 mmap:comedi_mmap, 1884 .mmap = comedi_mmap,
1885 poll:comedi_poll, 1885 .poll = comedi_poll,
1886 fasync:comedi_fasync, 1886 .fasync = comedi_fasync,
1887}; 1887};
1888 1888
1889struct class *comedi_class = NULL; 1889struct class *comedi_class;
1890static struct cdev comedi_cdev; 1890static struct cdev comedi_cdev;
1891 1891
1892static void comedi_cleanup_legacy_minors(void) 1892static void comedi_cleanup_legacy_minors(void)
1893{ 1893{
1894 unsigned i; 1894 unsigned i;
1895 for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) { 1895
1896 for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++)
1896 comedi_free_board_minor(i); 1897 comedi_free_board_minor(i);
1897 }
1898} 1898}
1899 1899
1900static int __init comedi_init(void) 1900static int __init comedi_init(void)
@@ -1902,13 +1902,14 @@ static int __init comedi_init(void)
1902 int i; 1902 int i;
1903 int retval; 1903 int retval;
1904 1904
1905 printk("comedi: version " COMEDI_RELEASE 1905 printk(KERN_INFO "comedi: version " COMEDI_RELEASE
1906 " - http://www.comedi.org\n"); 1906 " - http://www.comedi.org\n");
1907 1907
1908 memset(comedi_file_info_table, 0, sizeof(struct comedi_device_file_info*) * COMEDI_NUM_MINORS); 1908 memset(comedi_file_info_table, 0,
1909 sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS);
1909 1910
1910 retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0), 1911 retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
1911 COMEDI_NUM_MINORS, "comedi"); 1912 COMEDI_NUM_MINORS, "comedi");
1912 if (retval) 1913 if (retval)
1913 return -EIO; 1914 return -EIO;
1914 cdev_init(&comedi_cdev, &comedi_fops); 1915 cdev_init(&comedi_cdev, &comedi_fops);
@@ -1916,7 +1917,7 @@ static int __init comedi_init(void)
1916 kobject_set_name(&comedi_cdev.kobj, "comedi"); 1917 kobject_set_name(&comedi_cdev.kobj, "comedi");
1917 if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) { 1918 if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) {
1918 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), 1919 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
1919 COMEDI_NUM_MINORS); 1920 COMEDI_NUM_MINORS);
1920 return -EIO; 1921 return -EIO;
1921 } 1922 }
1922 comedi_class = class_create(THIS_MODULE, "comedi"); 1923 comedi_class = class_create(THIS_MODULE, "comedi");
@@ -1924,23 +1925,22 @@ static int __init comedi_init(void)
1924 printk("comedi: failed to create class"); 1925 printk("comedi: failed to create class");
1925 cdev_del(&comedi_cdev); 1926 cdev_del(&comedi_cdev);
1926 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), 1927 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
1927 COMEDI_NUM_MINORS); 1928 COMEDI_NUM_MINORS);
1928 return PTR_ERR(comedi_class); 1929 return PTR_ERR(comedi_class);
1929 } 1930 }
1930 1931
1931 /* XXX requires /proc interface */ 1932 /* XXX requires /proc interface */
1932 comedi_proc_init(); 1933 comedi_proc_init();
1933 1934
1934 // create devices files for legacy/manual use 1935 /* create devices files for legacy/manual use */
1935 for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) { 1936 for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) {
1936 int minor; 1937 int minor;
1937 minor = comedi_alloc_board_minor(NULL); 1938 minor = comedi_alloc_board_minor(NULL);
1938 if(minor < 0) 1939 if (minor < 0) {
1939 {
1940 comedi_cleanup_legacy_minors(); 1940 comedi_cleanup_legacy_minors();
1941 cdev_del(&comedi_cdev); 1941 cdev_del(&comedi_cdev);
1942 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), 1942 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
1943 COMEDI_NUM_MINORS); 1943 COMEDI_NUM_MINORS);
1944 return minor; 1944 return minor;
1945 } 1945 }
1946 } 1946 }
@@ -1957,10 +1957,9 @@ static void __exit comedi_cleanup(void)
1957 int i; 1957 int i;
1958 1958
1959 comedi_cleanup_legacy_minors(); 1959 comedi_cleanup_legacy_minors();
1960 for(i = 0; i < COMEDI_NUM_MINORS; ++i) 1960 for (i = 0; i < COMEDI_NUM_MINORS; ++i)
1961 {
1962 BUG_ON(comedi_file_info_table[i]); 1961 BUG_ON(comedi_file_info_table[i]);
1963 } 1962
1964 1963
1965 class_destroy(comedi_class); 1964 class_destroy(comedi_class);
1966 cdev_del(&comedi_cdev); 1965 cdev_del(&comedi_cdev);
@@ -1976,26 +1975,25 @@ static void __exit comedi_cleanup(void)
1976module_init(comedi_init); 1975module_init(comedi_init);
1977module_exit(comedi_cleanup); 1976module_exit(comedi_cleanup);
1978 1977
1979void comedi_error(const comedi_device * dev, const char *s) 1978void comedi_error(const comedi_device *dev, const char *s)
1980{ 1979{
1981 rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name, 1980 rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name,
1982 s); 1981 s);
1983} 1982}
1984 1983
1985void comedi_event(comedi_device * dev, comedi_subdevice * s) 1984void comedi_event(comedi_device *dev, comedi_subdevice *s)
1986{ 1985{
1987 comedi_async *async = s->async; 1986 comedi_async *async = s->async;
1988 unsigned runflags = 0; 1987 unsigned runflags = 0;
1989 unsigned runflags_mask = 0; 1988 unsigned runflags_mask = 0;
1990 1989
1991 //DPRINTK("comedi_event 0x%x\n",mask); 1990 /* DPRINTK("comedi_event 0x%x\n",mask); */
1992 1991
1993 if ((comedi_get_subdevice_runflags(s) & SRF_RUNNING) == 0) 1992 if ((comedi_get_subdevice_runflags(s) & SRF_RUNNING) == 0)
1994 return; 1993 return;
1995 1994
1996 if (s->async-> 1995 if (s->async->
1997 events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) 1996 events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
1998 {
1999 runflags_mask |= SRF_RUNNING; 1997 runflags_mask |= SRF_RUNNING;
2000 } 1998 }
2001 /* remember if an error event has occured, so an error 1999 /* remember if an error event has occured, so an error
@@ -2014,20 +2012,21 @@ void comedi_event(comedi_device * dev, comedi_subdevice * s)
2014 2012
2015 if (dev->rt) { 2013 if (dev->rt) {
2016#ifdef CONFIG_COMEDI_RT 2014#ifdef CONFIG_COMEDI_RT
2017 // pend wake up 2015 /* pend wake up */
2018 comedi_rt_pend_wakeup(&async->wait_head); 2016 comedi_rt_pend_wakeup(&async->wait_head);
2019#else 2017#else
2020 printk("BUG: comedi_event() code unreachable\n"); 2018 printk
2019 ("BUG: comedi_event() code unreachable\n");
2021#endif 2020#endif
2022 } else { 2021 } else {
2023 wake_up_interruptible(&async->wait_head); 2022 wake_up_interruptible(&async->wait_head);
2024 if (s->subdev_flags & SDF_CMD_READ) { 2023 if (s->subdev_flags & SDF_CMD_READ) {
2025 kill_fasync(&dev->async_queue, SIGIO, 2024 kill_fasync(&dev->async_queue, SIGIO,
2026 POLL_IN); 2025 POLL_IN);
2027 } 2026 }
2028 if (s->subdev_flags & SDF_CMD_WRITE) { 2027 if (s->subdev_flags & SDF_CMD_WRITE) {
2029 kill_fasync(&dev->async_queue, SIGIO, 2028 kill_fasync(&dev->async_queue, SIGIO,
2030 POLL_OUT); 2029 POLL_OUT);
2031 } 2030 }
2032 } 2031 }
2033 } else { 2032 } else {
@@ -2043,8 +2042,8 @@ void comedi_event(comedi_device * dev, comedi_subdevice * s)
2043 s->async->events = 0; 2042 s->async->events = 0;
2044} 2043}
2045 2044
2046void comedi_set_subdevice_runflags(comedi_subdevice * s, unsigned mask, 2045void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
2047 unsigned bits) 2046 unsigned bits)
2048{ 2047{
2049 unsigned long flags; 2048 unsigned long flags;
2050 2049
@@ -2054,7 +2053,7 @@ void comedi_set_subdevice_runflags(comedi_subdevice * s, unsigned mask,
2054 comedi_spin_unlock_irqrestore(&s->spin_lock, flags); 2053 comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
2055} 2054}
2056 2055
2057unsigned comedi_get_subdevice_runflags(comedi_subdevice * s) 2056unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
2058{ 2057{
2059 unsigned long flags; 2058 unsigned long flags;
2060 unsigned runflags; 2059 unsigned runflags;
@@ -2065,7 +2064,7 @@ unsigned comedi_get_subdevice_runflags(comedi_subdevice * s)
2065 return runflags; 2064 return runflags;
2066} 2065}
2067 2066
2068static int is_device_busy(comedi_device * dev) 2067static int is_device_busy(comedi_device *dev)
2069{ 2068{
2070 comedi_subdevice *s; 2069 comedi_subdevice *s;
2071 int i; 2070 int i;
@@ -2094,7 +2093,8 @@ void comedi_device_init(comedi_device *dev)
2094 2093
2095void comedi_device_cleanup(comedi_device *dev) 2094void comedi_device_cleanup(comedi_device *dev)
2096{ 2095{
2097 if(dev == NULL) return; 2096 if (dev == NULL)
2097 return;
2098 mutex_lock(&dev->mutex); 2098 mutex_lock(&dev->mutex);
2099 comedi_device_detach(dev); 2099 comedi_device_detach(dev);
2100 mutex_unlock(&dev->mutex); 2100 mutex_unlock(&dev->mutex);
@@ -2109,38 +2109,37 @@ int comedi_alloc_board_minor(struct device *hardware_device)
2109 unsigned i; 2109 unsigned i;
2110 2110
2111 info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); 2111 info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
2112 if(info == NULL) return -ENOMEM; 2112 if (info == NULL)
2113 return -ENOMEM;
2113 info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL); 2114 info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL);
2114 if(info->device == NULL) 2115 if (info->device == NULL) {
2115 {
2116 kfree(info); 2116 kfree(info);
2117 return -ENOMEM; 2117 return -ENOMEM;
2118 } 2118 }
2119 comedi_device_init(info->device); 2119 comedi_device_init(info->device);
2120 comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags); 2120 comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
2121 for(i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) 2121 for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) {
2122 { 2122 if (comedi_file_info_table[i] == NULL) {
2123 if(comedi_file_info_table[i] == NULL)
2124 {
2125 comedi_file_info_table[i] = info; 2123 comedi_file_info_table[i] = info;
2126 break; 2124 break;
2127 } 2125 }
2128 } 2126 }
2129 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); 2127 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
2130 if(i == COMEDI_NUM_BOARD_MINORS) 2128 if (i == COMEDI_NUM_BOARD_MINORS) {
2131 {
2132 comedi_device_cleanup(info->device); 2129 comedi_device_cleanup(info->device);
2133 kfree(info->device); 2130 kfree(info->device);
2134 kfree(info); 2131 kfree(info);
2135 rt_printk("comedi: error: ran out of minor numbers for board device files.\n"); 2132 rt_printk
2133 ("comedi: error: ran out of minor numbers for board device files.\n");
2136 return -EBUSY; 2134 return -EBUSY;
2137 } 2135 }
2138 info->device->minor = i; 2136 info->device->minor = i;
2139 csdev = COMEDI_DEVICE_CREATE(comedi_class, NULL, 2137 csdev = COMEDI_DEVICE_CREATE(comedi_class, NULL,
2140 MKDEV(COMEDI_MAJOR, i), NULL, hardware_device, "comedi%i", i); 2138 MKDEV(COMEDI_MAJOR, i), NULL,
2141 if(!IS_ERR(csdev)) { 2139 hardware_device, "comedi%i", i);
2140 if (!IS_ERR(csdev))
2142 info->device->class_dev = csdev; 2141 info->device->class_dev = csdev;
2143 } 2142
2144 return i; 2143 return i;
2145} 2144}
2146 2145
@@ -2155,14 +2154,12 @@ void comedi_free_board_minor(unsigned minor)
2155 comedi_file_info_table[minor] = NULL; 2154 comedi_file_info_table[minor] = NULL;
2156 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); 2155 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
2157 2156
2158 if(info) 2157 if (info) {
2159 {
2160 comedi_device *dev = info->device; 2158 comedi_device *dev = info->device;
2161 if(dev) 2159 if (dev) {
2162 { 2160 if (dev->class_dev) {
2163 if(dev->class_dev) 2161 device_destroy(comedi_class,
2164 { 2162 MKDEV(COMEDI_MAJOR, dev->minor));
2165 device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, dev->minor));
2166 } 2163 }
2167 comedi_device_cleanup(dev); 2164 comedi_device_cleanup(dev);
2168 kfree(dev); 2165 kfree(dev);
@@ -2179,33 +2176,33 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
2179 unsigned i; 2176 unsigned i;
2180 2177
2181 info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); 2178 info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
2182 if(info == NULL) return -ENOMEM; 2179 if (info == NULL)
2180 return -ENOMEM;
2183 info->device = dev; 2181 info->device = dev;
2184 info->read_subdevice = s; 2182 info->read_subdevice = s;
2185 info->write_subdevice = s; 2183 info->write_subdevice = s;
2186 comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags); 2184 comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
2187 for(i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) 2185 for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) {
2188 { 2186 if (comedi_file_info_table[i] == NULL) {
2189 if(comedi_file_info_table[i] == NULL)
2190 {
2191 comedi_file_info_table[i] = info; 2187 comedi_file_info_table[i] = info;
2192 break; 2188 break;
2193 } 2189 }
2194 } 2190 }
2195 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); 2191 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
2196 if(i == COMEDI_NUM_MINORS) 2192 if (i == COMEDI_NUM_MINORS) {
2197 {
2198 kfree(info); 2193 kfree(info);
2199 rt_printk("comedi: error: ran out of minor numbers for board device files.\n"); 2194 rt_printk
2195 ("comedi: error: ran out of minor numbers for board device files.\n");
2200 return -EBUSY; 2196 return -EBUSY;
2201 } 2197 }
2202 s->minor = i; 2198 s->minor = i;
2203 csdev = COMEDI_DEVICE_CREATE(comedi_class, dev->class_dev, 2199 csdev = COMEDI_DEVICE_CREATE(comedi_class, dev->class_dev,
2204 MKDEV(COMEDI_MAJOR, i), NULL, NULL, "comedi%i_subd%i", dev->minor, (int)(s - dev->subdevices)); 2200 MKDEV(COMEDI_MAJOR, i), NULL, NULL,
2205 if(!IS_ERR(csdev)) 2201 "comedi%i_subd%i", dev->minor,
2206 { 2202 (int)(s - dev->subdevices));
2203 if (!IS_ERR(csdev))
2207 s->class_dev = csdev; 2204 s->class_dev = csdev;
2208 } 2205
2209 return i; 2206 return i;
2210} 2207}
2211 2208
@@ -2214,8 +2211,10 @@ void comedi_free_subdevice_minor(comedi_subdevice *s)
2214 unsigned long flags; 2211 unsigned long flags;
2215 struct comedi_device_file_info *info; 2212 struct comedi_device_file_info *info;
2216 2213
2217 if(s == NULL) return; 2214 if (s == NULL)
2218 if(s->minor < 0) return; 2215 return;
2216 if (s->minor < 0)
2217 return;
2219 2218
2220 BUG_ON(s->minor >= COMEDI_NUM_MINORS); 2219 BUG_ON(s->minor >= COMEDI_NUM_MINORS);
2221 BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR); 2220 BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR);
@@ -2225,8 +2224,7 @@ void comedi_free_subdevice_minor(comedi_subdevice *s)
2225 comedi_file_info_table[s->minor] = NULL; 2224 comedi_file_info_table[s->minor] = NULL;
2226 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); 2225 comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
2227 2226
2228 if(s->class_dev) 2227 if (s->class_dev) {
2229 {
2230 device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor)); 2228 device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
2231 s->class_dev = NULL; 2229 s->class_dev = NULL;
2232 } 2230 }