comedidev.h revision 74b847f4d07bce1eaf84505d65aff42f14e5fb2f
1/* 2 include/linux/comedidev.h 3 header file for kernel-only structures, variables, and constants 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#ifndef _COMEDIDEV_H 25#define _COMEDIDEV_H 26 27#include <linux/kernel.h> 28#include <linux/module.h> 29#include <linux/version.h> 30#include <linux/kdev_t.h> 31#include <linux/slab.h> 32#include <linux/errno.h> 33#include <linux/spinlock.h> 34#include <linux/mutex.h> 35#include <linux/wait.h> 36#include <linux/mm.h> 37#include <linux/init.h> 38#include <linux/vmalloc.h> 39#include <linux/mm.h> 40#include "interrupt.h" 41#include <linux/dma-mapping.h> 42#include <linux/uaccess.h> 43#include <linux/io.h> 44 45#include "comedi.h" 46 47#define DPRINTK(format, args...) do { \ 48 if (comedi_debug) \ 49 printk(KERN_DEBUG "comedi: " format , ## args); \ 50} while (0) 51 52#define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) 53#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, COMEDI_MINORVERSION, COMEDI_MICROVERSION) 54#define COMEDI_RELEASE VERSION 55 56#define COMEDI_INITCLEANUP_NOMODULE(x) \ 57 static int __init x ## _init_module(void) \ 58 {return comedi_driver_register(&(x));} \ 59 static void __exit x ## _cleanup_module(void) \ 60 {comedi_driver_unregister(&(x));} \ 61 module_init(x ## _init_module); \ 62 module_exit(x ## _cleanup_module); \ 63 64#define COMEDI_MODULE_MACROS \ 65 MODULE_AUTHOR("Comedi http://www.comedi.org"); \ 66 MODULE_DESCRIPTION("Comedi low-level driver"); \ 67 MODULE_LICENSE("GPL"); \ 68 69#define COMEDI_INITCLEANUP(x) \ 70 COMEDI_MODULE_MACROS \ 71 COMEDI_INITCLEANUP_NOMODULE(x) 72 73#define COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) \ 74 static int __devinit comedi_driver ## _pci_probe(struct pci_dev *dev, \ 75 const struct pci_device_id *ent) \ 76 { \ 77 return comedi_pci_auto_config(dev, comedi_driver.driver_name); \ 78 } \ 79 static void __devexit comedi_driver ## _pci_remove(struct pci_dev *dev) \ 80 { \ 81 comedi_pci_auto_unconfig(dev); \ 82 } \ 83 static struct pci_driver comedi_driver ## _pci_driver = \ 84 { \ 85 .id_table = pci_id_table, \ 86 .probe = &comedi_driver ## _pci_probe, \ 87 .remove = __devexit_p(&comedi_driver ## _pci_remove) \ 88 }; \ 89 static int __init comedi_driver ## _init_module(void) \ 90 { \ 91 int retval; \ 92 retval = comedi_driver_register(&comedi_driver); \ 93 if (retval < 0) \ 94 return retval; \ 95 comedi_driver ## _pci_driver.name = (char *)comedi_driver.driver_name; \ 96 return pci_register_driver(&comedi_driver ## _pci_driver); \ 97 } \ 98 static void __exit comedi_driver ## _cleanup_module(void) \ 99 { \ 100 pci_unregister_driver(&comedi_driver ## _pci_driver); \ 101 comedi_driver_unregister(&comedi_driver); \ 102 } \ 103 module_init(comedi_driver ## _init_module); \ 104 module_exit(comedi_driver ## _cleanup_module); 105 106#define COMEDI_PCI_INITCLEANUP(comedi_driver, pci_id_table) \ 107 COMEDI_MODULE_MACROS \ 108 COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) 109 110#define PCI_VENDOR_ID_INOVA 0x104c 111#define PCI_VENDOR_ID_NATINST 0x1093 112#define PCI_VENDOR_ID_DATX 0x1116 113#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 114#define PCI_VENDOR_ID_ADVANTECH 0x13fe 115#define PCI_VENDOR_ID_RTD 0x1435 116#define PCI_VENDOR_ID_AMPLICON 0x14dc 117#define PCI_VENDOR_ID_ADLINK 0x144a 118#define PCI_VENDOR_ID_ICP 0x104c 119#define PCI_VENDOR_ID_CONTEC 0x1221 120#define PCI_VENDOR_ID_MEILHAUS 0x1402 121 122#define COMEDI_NUM_MINORS 0x100 123#define COMEDI_NUM_LEGACY_MINORS 0x10 124#define COMEDI_NUM_BOARD_MINORS 0x30 125#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS 126 127typedef struct comedi_device_struct comedi_device; 128typedef struct comedi_subdevice_struct comedi_subdevice; 129typedef struct comedi_async_struct comedi_async; 130typedef struct comedi_driver_struct comedi_driver; 131typedef struct comedi_lrange_struct comedi_lrange; 132 133typedef struct device device_create_result_type; 134 135#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \ 136 device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt) 137 138struct comedi_subdevice_struct { 139 comedi_device *device; 140 int type; 141 int n_chan; 142 volatile int subdev_flags; 143 int len_chanlist; /* maximum length of channel/gain list */ 144 145 void *private; 146 147 comedi_async *async; 148 149 void *lock; 150 void *busy; 151 unsigned runflags; 152 spinlock_t spin_lock; 153 154 int io_bits; 155 156 lsampl_t maxdata; /* if maxdata==0, use list */ 157 const lsampl_t *maxdata_list; /* list is channel specific */ 158 159 unsigned int flags; 160 const unsigned int *flaglist; 161 162 unsigned int settling_time_0; 163 164 const comedi_lrange *range_table; 165 const comedi_lrange *const *range_table_list; 166 167 unsigned int *chanlist; /* driver-owned chanlist (not used) */ 168 169 int (*insn_read) (comedi_device *, comedi_subdevice *, comedi_insn *, 170 lsampl_t *); 171 int (*insn_write) (comedi_device *, comedi_subdevice *, comedi_insn *, 172 lsampl_t *); 173 int (*insn_bits) (comedi_device *, comedi_subdevice *, comedi_insn *, 174 lsampl_t *); 175 int (*insn_config) (comedi_device *, comedi_subdevice *, comedi_insn *, 176 lsampl_t *); 177 178 int (*do_cmd) (comedi_device *, comedi_subdevice *); 179 int (*do_cmdtest) (comedi_device *, comedi_subdevice *, comedi_cmd *); 180 int (*poll) (comedi_device *, comedi_subdevice *); 181 int (*cancel) (comedi_device *, comedi_subdevice *); 182 /* int (*do_lock)(comedi_device *,comedi_subdevice *); */ 183 /* int (*do_unlock)(comedi_device *,comedi_subdevice *); */ 184 185 /* called when the buffer changes */ 186 int (*buf_change) (comedi_device *dev, comedi_subdevice *s, 187 unsigned long new_size); 188 189 void (*munge) (comedi_device *dev, comedi_subdevice *s, void *data, 190 unsigned int num_bytes, unsigned int start_chan_index); 191 enum dma_data_direction async_dma_dir; 192 193 unsigned int state; 194 195 device_create_result_type *class_dev; 196 int minor; 197}; 198 199struct comedi_buf_page { 200 void *virt_addr; 201 dma_addr_t dma_addr; 202}; 203 204struct comedi_async_struct { 205 comedi_subdevice *subdevice; 206 207 void *prealloc_buf; /* pre-allocated buffer */ 208 unsigned int prealloc_bufsz; /* buffer size, in bytes */ 209 struct comedi_buf_page *buf_page_list; /* virtual and dma address of each page */ 210 unsigned n_buf_pages; /* num elements in buf_page_list */ 211 212 unsigned int max_bufsize; /* maximum buffer size, bytes */ 213 unsigned int mmap_count; /* current number of mmaps of prealloc_buf */ 214 215 unsigned int buf_write_count; /* byte count for writer (write completed) */ 216 unsigned int buf_write_alloc_count; /* byte count for writer (allocated for writing) */ 217 unsigned int buf_read_count; /* byte count for reader (read completed) */ 218 unsigned int buf_read_alloc_count; /* byte count for reader (allocated for reading) */ 219 220 unsigned int buf_write_ptr; /* buffer marker for writer */ 221 unsigned int buf_read_ptr; /* buffer marker for reader */ 222 223 unsigned int cur_chan; /* useless channel marker for interrupt */ 224 /* number of bytes that have been received for current scan */ 225 unsigned int scan_progress; 226 /* keeps track of where we are in chanlist as for munging */ 227 unsigned int munge_chan; 228 /* number of bytes that have been munged */ 229 unsigned int munge_count; 230 /* buffer marker for munging */ 231 unsigned int munge_ptr; 232 233 unsigned int events; /* events that have occurred */ 234 235 comedi_cmd cmd; 236 237 wait_queue_head_t wait_head; 238 239 /* callback stuff */ 240 unsigned int cb_mask; 241 int (*cb_func) (unsigned int flags, void *); 242 void *cb_arg; 243 244 int (*inttrig) (comedi_device *dev, comedi_subdevice *s, 245 unsigned int x); 246}; 247 248struct comedi_driver_struct { 249 struct comedi_driver_struct *next; 250 251 const char *driver_name; 252 struct module *module; 253 int (*attach) (comedi_device *, comedi_devconfig *); 254 int (*detach) (comedi_device *); 255 256 /* number of elements in board_name and board_id arrays */ 257 unsigned int num_names; 258 const char *const *board_name; 259 /* offset in bytes from one board name pointer to the next */ 260 int offset; 261}; 262 263struct comedi_device_struct { 264 int use_count; 265 comedi_driver *driver; 266 void *private; 267 268 device_create_result_type *class_dev; 269 int minor; 270 /* hw_dev is passed to dma_alloc_coherent when allocating async buffers 271 * for subdevices that have async_dma_dir set to something other than 272 * DMA_NONE */ 273 struct device *hw_dev; 274 275 const char *board_name; 276 const void *board_ptr; 277 int attached; 278 int rt; 279 spinlock_t spinlock; 280 struct mutex mutex; 281 int in_request_module; 282 283 int n_subdevices; 284 comedi_subdevice *subdevices; 285 286 /* dumb */ 287 unsigned long iobase; 288 unsigned int irq; 289 290 comedi_subdevice *read_subdev; 291 comedi_subdevice *write_subdev; 292 293 struct fasync_struct *async_queue; 294 295 void (*open) (comedi_device *dev); 296 void (*close) (comedi_device *dev); 297}; 298 299struct comedi_device_file_info { 300 comedi_device *device; 301 comedi_subdevice *read_subdevice; 302 comedi_subdevice *write_subdevice; 303}; 304 305#ifdef CONFIG_COMEDI_DEBUG 306extern int comedi_debug; 307#else 308static const int comedi_debug; 309#endif 310 311/* 312 * function prototypes 313 */ 314 315void comedi_event(comedi_device *dev, comedi_subdevice *s); 316void comedi_error(const comedi_device *dev, const char *s); 317 318/* we can expand the number of bits used to encode devices/subdevices into 319 the minor number soon, after more distros support > 8 bit minor numbers 320 (like after Debian Etch gets released) */ 321enum comedi_minor_bits { 322 COMEDI_DEVICE_MINOR_MASK = 0xf, 323 COMEDI_SUBDEVICE_MINOR_MASK = 0xf0 324}; 325static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4; 326static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1; 327 328struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor); 329 330static inline comedi_subdevice *comedi_get_read_subdevice( 331 const struct comedi_device_file_info *info) 332{ 333 if (info->read_subdevice) 334 return info->read_subdevice; 335 if (info->device == NULL) 336 return NULL; 337 return info->device->read_subdev; 338} 339 340static inline comedi_subdevice *comedi_get_write_subdevice( 341 const struct comedi_device_file_info *info) 342{ 343 if (info->write_subdevice) 344 return info->write_subdevice; 345 if (info->device == NULL) 346 return NULL; 347 return info->device->write_subdev; 348} 349 350void comedi_device_detach(comedi_device *dev); 351int comedi_device_attach(comedi_device *dev, comedi_devconfig *it); 352int comedi_driver_register(comedi_driver *); 353int comedi_driver_unregister(comedi_driver *); 354 355void init_polling(void); 356void cleanup_polling(void); 357void start_polling(comedi_device *); 358void stop_polling(comedi_device *); 359 360int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long 361 new_size); 362 363#ifdef CONFIG_PROC_FS 364void comedi_proc_init(void); 365void comedi_proc_cleanup(void); 366#else 367static inline void comedi_proc_init(void) 368{ 369} 370static inline void comedi_proc_cleanup(void) 371{ 372} 373#endif 374 375/* subdevice runflags */ 376enum subdevice_runflags { 377 SRF_USER = 0x00000001, 378 SRF_RT = 0x00000002, 379 /* indicates an COMEDI_CB_ERROR event has occurred since the last 380 * command was started */ 381 SRF_ERROR = 0x00000004, 382 SRF_RUNNING = 0x08000000 383}; 384 385/* 386 various internal comedi functions 387 */ 388 389int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg); 390int check_chanlist(comedi_subdevice *s, int n, unsigned int *chanlist); 391void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask, 392 unsigned bits); 393unsigned comedi_get_subdevice_runflags(comedi_subdevice *s); 394int insn_inval(comedi_device *dev, comedi_subdevice *s, 395 comedi_insn *insn, lsampl_t *data); 396 397/* range stuff */ 398 399#define RANGE(a, b) {(a)*1e6, (b)*1e6, 0} 400#define RANGE_ext(a, b) {(a)*1e6, (b)*1e6, RF_EXTERNAL} 401#define RANGE_mA(a, b) {(a)*1e6, (b)*1e6, UNIT_mA} 402#define RANGE_unitless(a, b) {(a)*1e6, (b)*1e6, 0} /* XXX */ 403#define BIP_RANGE(a) {-(a)*1e6, (a)*1e6, 0} 404#define UNI_RANGE(a) {0, (a)*1e6, 0} 405 406extern const comedi_lrange range_bipolar10; 407extern const comedi_lrange range_bipolar5; 408extern const comedi_lrange range_bipolar2_5; 409extern const comedi_lrange range_unipolar10; 410extern const comedi_lrange range_unipolar5; 411extern const comedi_lrange range_unknown; 412 413#define range_digital range_unipolar5 414 415#if __GNUC__ >= 3 416#define GCC_ZERO_LENGTH_ARRAY 417#else 418#define GCC_ZERO_LENGTH_ARRAY 0 419#endif 420 421struct comedi_lrange_struct { 422 int length; 423 comedi_krange range[GCC_ZERO_LENGTH_ARRAY]; 424}; 425 426/* some silly little inline functions */ 427 428static inline int alloc_subdevices(comedi_device *dev, 429 unsigned int num_subdevices) 430{ 431 unsigned i; 432 433 dev->n_subdevices = num_subdevices; 434 dev->subdevices = 435 kcalloc(num_subdevices, sizeof(comedi_subdevice), GFP_KERNEL); 436 if (!dev->subdevices) 437 return -ENOMEM; 438 for (i = 0; i < num_subdevices; ++i) { 439 dev->subdevices[i].device = dev; 440 dev->subdevices[i].async_dma_dir = DMA_NONE; 441 spin_lock_init(&dev->subdevices[i].spin_lock); 442 dev->subdevices[i].minor = -1; 443 } 444 return 0; 445} 446 447static inline int alloc_private(comedi_device *dev, int size) 448{ 449 dev->private = kzalloc(size, GFP_KERNEL); 450 if (!dev->private) 451 return -ENOMEM; 452 return 0; 453} 454 455static inline unsigned int bytes_per_sample(const comedi_subdevice *subd) 456{ 457 if (subd->subdev_flags & SDF_LSAMPL) 458 return sizeof(lsampl_t); 459 else 460 return sizeof(sampl_t); 461} 462 463/* must be used in attach to set dev->hw_dev if you wish to dma directly 464into comedi's buffer */ 465static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev) 466{ 467 if (dev->hw_dev) 468 put_device(dev->hw_dev); 469 470 dev->hw_dev = hw_dev; 471 if (dev->hw_dev) { 472 dev->hw_dev = get_device(dev->hw_dev); 473 BUG_ON(dev->hw_dev == NULL); 474 } 475} 476 477int comedi_buf_put(comedi_async *async, sampl_t x); 478int comedi_buf_get(comedi_async *async, sampl_t *x); 479 480unsigned int comedi_buf_write_n_available(comedi_async *async); 481unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes); 482unsigned int comedi_buf_write_alloc_strict(comedi_async *async, 483 unsigned int nbytes); 484unsigned comedi_buf_write_free(comedi_async *async, unsigned int nbytes); 485unsigned comedi_buf_read_alloc(comedi_async *async, unsigned nbytes); 486unsigned comedi_buf_read_free(comedi_async *async, unsigned int nbytes); 487unsigned int comedi_buf_read_n_available(comedi_async *async); 488void comedi_buf_memcpy_to(comedi_async *async, unsigned int offset, 489 const void *source, unsigned int num_bytes); 490void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset, 491 void *destination, unsigned int num_bytes); 492static inline unsigned comedi_buf_write_n_allocated(comedi_async *async) 493{ 494 return async->buf_write_alloc_count - async->buf_write_count; 495} 496static inline unsigned comedi_buf_read_n_allocated(comedi_async *async) 497{ 498 return async->buf_read_alloc_count - async->buf_read_count; 499} 500 501void comedi_reset_async_buf(comedi_async *async); 502 503static inline void *comedi_aux_data(int options[], int n) 504{ 505 unsigned long address; 506 unsigned long addressLow; 507 int bit_shift; 508 if (sizeof(int) >= sizeof(void *)) 509 address = options[COMEDI_DEVCONF_AUX_DATA_LO]; 510 else { 511 address = options[COMEDI_DEVCONF_AUX_DATA_HI]; 512 bit_shift = sizeof(int) * 8; 513 address <<= bit_shift; 514 addressLow = options[COMEDI_DEVCONF_AUX_DATA_LO]; 515 addressLow &= (1UL << bit_shift) - 1; 516 address |= addressLow; 517 } 518 if (n >= 1) 519 address += options[COMEDI_DEVCONF_AUX_DATA0_LENGTH]; 520 if (n >= 2) 521 address += options[COMEDI_DEVCONF_AUX_DATA1_LENGTH]; 522 if (n >= 3) 523 address += options[COMEDI_DEVCONF_AUX_DATA2_LENGTH]; 524 BUG_ON(n > 3); 525 return (void *)address; 526} 527 528int comedi_alloc_board_minor(struct device *hardware_device); 529void comedi_free_board_minor(unsigned minor); 530int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s); 531void comedi_free_subdevice_minor(comedi_subdevice *s); 532int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name); 533void comedi_pci_auto_unconfig(struct pci_dev *pcidev); 534 535#include "comedi_rt.h" 536 537#endif /* _COMEDIDEV_H */ 538