diff options
Diffstat (limited to 'drivers/staging/comedi/comedidev.h')
| -rw-r--r-- | drivers/staging/comedi/comedidev.h | 509 | 
1 files changed, 284 insertions, 225 deletions
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 68aa9176d24..8f4e44bfbe0 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -14,58 +14,29 @@      but WITHOUT ANY WARRANTY; without even the implied warranty of      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      GNU General Public License for more details. - -    You should have received a copy of the GNU General Public License -    along with this program; if not, write to the Free Software -    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -  */  #ifndef _COMEDIDEV_H  #define _COMEDIDEV_H -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/kdev_t.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/spinlock.h> -#include <linux/mutex.h> -#include <linux/wait.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/vmalloc.h>  #include <linux/dma-mapping.h> -#include <linux/uaccess.h> -#include <linux/io.h> -#include <linux/timer.h> +#include <linux/mutex.h> +#include <linux/spinlock_types.h> +#include <linux/rwsem.h> +#include <linux/kref.h>  #include "comedi.h" -#define DPRINTK(format, args...)	do {		\ -	if (comedi_debug)				\ -		printk(KERN_DEBUG "comedi: " format , ## args);	\ -} while (0) -  #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))  #define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \  	COMEDI_MINORVERSION, COMEDI_MICROVERSION)  #define COMEDI_RELEASE VERSION -#define PCI_VENDOR_ID_ADLINK		0x144a -#define PCI_VENDOR_ID_ICP		0x104c -#define PCI_VENDOR_ID_CONTEC		0x1221 - -#define COMEDI_NUM_MINORS 0x100  #define COMEDI_NUM_BOARD_MINORS 0x30 -#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS - -#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \ -	device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)  struct comedi_subdevice {  	struct comedi_device *device; +	int index;  	int type;  	int n_chan;  	int subdev_flags; @@ -80,46 +51,41 @@ struct comedi_subdevice {  	unsigned runflags;  	spinlock_t spin_lock; -	int io_bits; +	unsigned int io_bits;  	unsigned int maxdata;	/* if maxdata==0, use list */  	const unsigned int *maxdata_list;	/* list is channel specific */ -	unsigned int flags; -	const unsigned int *flaglist; - -	unsigned int settling_time_0; -  	const struct comedi_lrange *range_table;  	const struct comedi_lrange *const *range_table_list;  	unsigned int *chanlist;	/* driver-owned chanlist (not used) */ -	int (*insn_read) (struct comedi_device *, struct comedi_subdevice *, +	int (*insn_read)(struct comedi_device *, struct comedi_subdevice *, +			 struct comedi_insn *, unsigned int *); +	int (*insn_write)(struct comedi_device *, struct comedi_subdevice *,  			  struct comedi_insn *, unsigned int *); -	int (*insn_write) (struct comedi_device *, struct comedi_subdevice *, +	int (*insn_bits)(struct comedi_device *, struct comedi_subdevice *, +			 struct comedi_insn *, unsigned int *); +	int (*insn_config)(struct comedi_device *, struct comedi_subdevice *,  			   struct comedi_insn *, unsigned int *); -	int (*insn_bits) (struct comedi_device *, struct comedi_subdevice *, -			  struct comedi_insn *, unsigned int *); -	int (*insn_config) (struct comedi_device *, struct comedi_subdevice *, -			    struct comedi_insn *, unsigned int *); - -	int (*do_cmd) (struct comedi_device *, struct comedi_subdevice *); -	int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, -			   struct comedi_cmd *); -	int (*poll) (struct comedi_device *, struct comedi_subdevice *); -	int (*cancel) (struct comedi_device *, struct comedi_subdevice *); + +	int (*do_cmd)(struct comedi_device *, struct comedi_subdevice *); +	int (*do_cmdtest)(struct comedi_device *, struct comedi_subdevice *, +			  struct comedi_cmd *); +	int (*poll)(struct comedi_device *, struct comedi_subdevice *); +	int (*cancel)(struct comedi_device *, struct comedi_subdevice *);  	/* int (*do_lock)(struct comedi_device *, struct comedi_subdevice *); */  	/* int (*do_unlock)(struct comedi_device *, \  			struct comedi_subdevice *); */  	/* called when the buffer changes */ -	int (*buf_change) (struct comedi_device *dev, -			   struct comedi_subdevice *s, unsigned long new_size); +	int (*buf_change)(struct comedi_device *dev, +			  struct comedi_subdevice *s, unsigned long new_size); -	void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, -		       void *data, unsigned int num_bytes, -		       unsigned int start_chan_index); +	void (*munge)(struct comedi_device *dev, struct comedi_subdevice *s, +		      void *data, unsigned int num_bytes, +		      unsigned int start_chan_index);  	enum dma_data_direction async_dma_dir;  	unsigned int state; @@ -133,18 +99,20 @@ struct comedi_buf_page {  	dma_addr_t dma_addr;  }; -struct comedi_async { -	struct comedi_subdevice *subdevice; +struct comedi_buf_map { +	struct device *dma_hw_dev; +	struct comedi_buf_page *page_list; +	unsigned int n_pages; +	enum dma_data_direction dma_dir; +	struct kref refcount; +}; +struct comedi_async {  	void *prealloc_buf;	/* pre-allocated buffer */  	unsigned int prealloc_bufsz;	/* buffer size, in bytes */ -	/* virtual and dma address of each page */ -	struct comedi_buf_page *buf_page_list; -	unsigned n_buf_pages;	/* num elements in buf_page_list */ +	struct comedi_buf_map *buf_map;	/* map of buffer pages */  	unsigned int max_bufsize;	/* maximum buffer size, bytes */ -	/* current number of mmaps of prealloc_buf */ -	unsigned int mmap_count;  	/* byte count for writer (write completed) */  	unsigned int buf_write_count; @@ -174,13 +142,10 @@ struct comedi_async {  	wait_queue_head_t wait_head; -	/* callback stuff */  	unsigned int cb_mask; -	int (*cb_func) (unsigned int flags, void *); -	void *cb_arg; -	int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s, -			unsigned int x); +	int (*inttrig)(struct comedi_device *dev, struct comedi_subdevice *s, +		       unsigned int x);  };  struct comedi_driver { @@ -188,8 +153,9 @@ struct comedi_driver {  	const char *driver_name;  	struct module *module; -	int (*attach) (struct comedi_device *, struct comedi_devconfig *); -	int (*detach) (struct comedi_device *); +	int (*attach)(struct comedi_device *, struct comedi_devconfig *); +	void (*detach)(struct comedi_device *); +	int (*auto_attach)(struct comedi_device *, unsigned long);  	/* number of elements in board_name and board_id arrays */  	unsigned int num_names; @@ -205,6 +171,7 @@ struct comedi_device {  	struct device *class_dev;  	int minor; +	unsigned int detach_count;  	/* hw_dev is passed to dma_alloc_coherent when allocating async buffers  	 * for subdevices that have async_dma_dir set to something other than  	 * DMA_NONE */ @@ -212,16 +179,19 @@ struct comedi_device {  	const char *board_name;  	const void *board_ptr; -	int attached; +	bool attached:1; +	bool ioenabled:1;  	spinlock_t spinlock;  	struct mutex mutex; -	int in_request_module; +	struct rw_semaphore attach_lock; +	struct kref refcount;  	int n_subdevices;  	struct comedi_subdevice *subdevices;  	/* dumb */  	unsigned long iobase; +	unsigned long iolen;  	unsigned int irq;  	struct comedi_subdevice *read_subdev; @@ -229,21 +199,14 @@ struct comedi_device {  	struct fasync_struct *async_queue; -	int (*open) (struct comedi_device *dev); -	void (*close) (struct comedi_device *dev); +	int (*open)(struct comedi_device *dev); +	void (*close)(struct comedi_device *dev);  }; -struct comedi_device_file_info { -	struct comedi_device *device; -	struct comedi_subdevice *read_subdevice; -	struct comedi_subdevice *write_subdevice; -}; - -#ifdef CONFIG_COMEDI_DEBUG -extern int comedi_debug; -#else -static const int comedi_debug; -#endif +static inline const void *comedi_board(const struct comedi_device *dev) +{ +	return dev->board_ptr; +}  /*   * function prototypes @@ -262,66 +225,31 @@ enum comedi_minor_bits {  static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;  static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1; -struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor); - -static inline struct comedi_subdevice *comedi_get_read_subdevice( -	const struct comedi_device_file_info *info) -{ -	if (info->read_subdevice) -		return info->read_subdevice; -	if (info->device == NULL) -		return NULL; -	return info->device->read_subdev; -} - -static inline struct comedi_subdevice *comedi_get_write_subdevice( -	const struct comedi_device_file_info *info) -{ -	if (info->write_subdevice) -		return info->write_subdevice; -	if (info->device == NULL) -		return NULL; -	return info->device->write_subdev; -} - -void comedi_device_detach(struct comedi_device *dev); -int comedi_device_attach(struct comedi_device *dev, -			 struct comedi_devconfig *it); -int comedi_driver_register(struct comedi_driver *); -int comedi_driver_unregister(struct comedi_driver *); +struct comedi_device *comedi_dev_get_from_minor(unsigned minor); +int comedi_dev_put(struct comedi_device *dev);  void init_polling(void);  void cleanup_polling(void);  void start_polling(struct comedi_device *);  void stop_polling(struct comedi_device *); -#ifdef CONFIG_PROC_FS -void comedi_proc_init(void); -void comedi_proc_cleanup(void); -#else -static inline void comedi_proc_init(void) -{ -} - -static inline void comedi_proc_cleanup(void) -{ -} -#endif -  /* subdevice runflags */  enum subdevice_runflags { -	SRF_USER = 0x00000001,  	SRF_RT = 0x00000002,  	/* indicates an COMEDI_CB_ERROR event has occurred since the last  	 * command was started */  	SRF_ERROR = 0x00000004, -	SRF_RUNNING = 0x08000000 +	SRF_RUNNING = 0x08000000, +	SRF_FREE_SPRIV = 0x80000000,	/* free s->private on detach */  }; +bool comedi_is_subdevice_running(struct comedi_subdevice *s); + +void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size); +  int comedi_check_chanlist(struct comedi_subdevice *s,  			  int n,  			  unsigned int *chanlist); -unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s);  /* range stuff */ @@ -337,6 +265,10 @@ extern const struct comedi_lrange range_bipolar5;  extern const struct comedi_lrange range_bipolar2_5;  extern const struct comedi_lrange range_unipolar10;  extern const struct comedi_lrange range_unipolar5; +extern const struct comedi_lrange range_unipolar2_5; +extern const struct comedi_lrange range_0_20mA; +extern const struct comedi_lrange range_4_20mA; +extern const struct comedi_lrange range_0_32mA;  extern const struct comedi_lrange range_unknown;  #define range_digital		range_unipolar5 @@ -352,34 +284,37 @@ struct comedi_lrange {  	struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];  }; -/* some silly little inline functions */ +static inline bool comedi_range_is_bipolar(struct comedi_subdevice *s, +					   unsigned int range) +{ +	return s->range_table->range[range].min < 0; +} + +static inline bool comedi_range_is_unipolar(struct comedi_subdevice *s, +					    unsigned int range) +{ +	return s->range_table->range[range].min >= 0; +} + +static inline bool comedi_chan_range_is_bipolar(struct comedi_subdevice *s, +						unsigned int chan, +						unsigned int range) +{ +	return s->range_table_list[chan]->range[range].min < 0; +} -static inline int alloc_subdevices(struct comedi_device *dev, -				   unsigned int num_subdevices) +static inline bool comedi_chan_range_is_unipolar(struct comedi_subdevice *s, +						 unsigned int chan, +						 unsigned int range)  { -	unsigned i; - -	dev->n_subdevices = num_subdevices; -	dev->subdevices = -	    kcalloc(num_subdevices, sizeof(struct comedi_subdevice), -		    GFP_KERNEL); -	if (!dev->subdevices) -		return -ENOMEM; -	for (i = 0; i < num_subdevices; ++i) { -		dev->subdevices[i].device = dev; -		dev->subdevices[i].async_dma_dir = DMA_NONE; -		spin_lock_init(&dev->subdevices[i].spin_lock); -		dev->subdevices[i].minor = -1; -	} -	return 0; +	return s->range_table_list[chan]->range[range].min >= 0;  } -static inline int alloc_private(struct comedi_device *dev, int size) +/* munge between offset binary and two's complement values */ +static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s, +					       unsigned int val)  { -	dev->private = kzalloc(size, GFP_KERNEL); -	if (!dev->private) -		return -ENOMEM; -	return 0; +	return val ^ s->maxdata ^ (s->maxdata >> 1);  }  static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd) @@ -390,92 +325,216 @@ static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)  		return sizeof(short);  } -/* must be used in attach to set dev->hw_dev if you wish to dma directly -into comedi's buffer */ -static inline void comedi_set_hw_dev(struct comedi_device *dev, -				     struct device *hw_dev) -{ -	if (dev->hw_dev) -		put_device(dev->hw_dev); - -	dev->hw_dev = hw_dev; -	if (dev->hw_dev) { -		dev->hw_dev = get_device(dev->hw_dev); -		BUG_ON(dev->hw_dev == NULL); -	} -} +/* + * Must set dev->hw_dev if you wish to dma directly into comedi's buffer. + * Also useful for retrieving a previously configured hardware device of + * known bus type.  Set automatically for auto-configured devices. + * Automatically set to NULL when detaching hardware device. + */ +int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev); + +unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, unsigned int n); +unsigned int comedi_buf_write_free(struct comedi_subdevice *s, unsigned int n); + +unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s); +unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int n); +unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n); + +int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); +int comedi_buf_get(struct comedi_subdevice *s, unsigned short *x); -int comedi_buf_put(struct comedi_async *async, short x); -int comedi_buf_get(struct comedi_async *async, short *x); - -unsigned int comedi_buf_write_n_available(struct comedi_async *async); -unsigned int comedi_buf_write_alloc(struct comedi_async *async, -				    unsigned int nbytes); -unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async, -					   unsigned int nbytes); -unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes); -unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes); -unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes); -unsigned int comedi_buf_read_n_available(struct comedi_async *async); -void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset, +void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset,  			  const void *source, unsigned int num_bytes); -void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset, +void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset,  			    void *destination, unsigned int num_bytes); -static inline unsigned comedi_buf_write_n_allocated(struct comedi_async *async) + +/* drivers.c - general comedi driver functions */ + +#define COMEDI_TIMEOUT_MS	1000 + +int comedi_timeout(struct comedi_device *, struct comedi_subdevice *, +		   struct comedi_insn *, +		   int (*cb)(struct comedi_device *, struct comedi_subdevice *, +			     struct comedi_insn *, unsigned long context), +		   unsigned long context); + +int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *, +			   struct comedi_insn *, unsigned int *data, +			   unsigned int mask); +unsigned int comedi_dio_update_state(struct comedi_subdevice *, +				     unsigned int *data); + +void *comedi_alloc_devpriv(struct comedi_device *, size_t); +int comedi_alloc_subdevices(struct comedi_device *, int); + +int comedi_load_firmware(struct comedi_device *, struct device *, +			 const char *name, +			 int (*cb)(struct comedi_device *, +				   const u8 *data, size_t size, +				   unsigned long context), +			 unsigned long context); + +int __comedi_request_region(struct comedi_device *, +			    unsigned long start, unsigned long len); +int comedi_request_region(struct comedi_device *, +			  unsigned long start, unsigned long len); +void comedi_legacy_detach(struct comedi_device *); + +int comedi_auto_config(struct device *, struct comedi_driver *, +		       unsigned long context); +void comedi_auto_unconfig(struct device *); + +int comedi_driver_register(struct comedi_driver *); +void comedi_driver_unregister(struct comedi_driver *); + +/** + * module_comedi_driver() - Helper macro for registering a comedi driver + * @__comedi_driver: comedi_driver struct + * + * Helper macro for comedi drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only use + * this macro once, and calling it replaces module_init() and module_exit(). + */ +#define module_comedi_driver(__comedi_driver) \ +	module_driver(__comedi_driver, comedi_driver_register, \ +			comedi_driver_unregister) + +#ifdef CONFIG_COMEDI_PCI_DRIVERS + +/* comedi_pci.c - comedi PCI driver specific functions */ + +/* + * PCI Vendor IDs not in <linux/pci_ids.h> + */ +#define PCI_VENDOR_ID_KOLTER		0x1001 +#define PCI_VENDOR_ID_ICP		0x104c +#define PCI_VENDOR_ID_DT		0x1116 +#define PCI_VENDOR_ID_IOTECH		0x1616 +#define PCI_VENDOR_ID_CONTEC		0x1221 +#define PCI_VENDOR_ID_RTD		0x1435 +#define PCI_VENDOR_ID_HUMUSOFT		0x186c + +struct pci_dev; +struct pci_driver; + +struct pci_dev *comedi_to_pci_dev(struct comedi_device *); + +int comedi_pci_enable(struct comedi_device *); +void comedi_pci_disable(struct comedi_device *); + +int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *, +			   unsigned long context); +void comedi_pci_auto_unconfig(struct pci_dev *); + +int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *); +void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); + +/** + * module_comedi_pci_driver() - Helper macro for registering a comedi PCI driver + * @__comedi_driver: comedi_driver struct + * @__pci_driver: pci_driver struct + * + * Helper macro for comedi PCI drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_pci_driver(__comedi_driver, __pci_driver) \ +	module_driver(__comedi_driver, comedi_pci_driver_register, \ +			comedi_pci_driver_unregister, &(__pci_driver)) + +#else + +/* + * Some of the comedi mixed ISA/PCI drivers call the PCI specific + * functions. Provide some dummy functions if CONFIG_COMEDI_PCI_DRIVERS + * is not enabled. + */ + +static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev)  { -	return async->buf_write_alloc_count - async->buf_write_count; +	return NULL;  } -static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async) +static inline int comedi_pci_enable(struct comedi_device *dev)  { -	return async->buf_read_alloc_count - async->buf_read_count; +	return -ENOSYS;  } -static inline void *comedi_aux_data(int options[], int n) +static inline void comedi_pci_disable(struct comedi_device *dev)  { -	unsigned long address; -	unsigned long addressLow; -	int bit_shift; -	if (sizeof(int) >= sizeof(void *)) -		address = options[COMEDI_DEVCONF_AUX_DATA_LO]; -	else { -		address = options[COMEDI_DEVCONF_AUX_DATA_HI]; -		bit_shift = sizeof(int) * 8; -		address <<= bit_shift; -		addressLow = options[COMEDI_DEVCONF_AUX_DATA_LO]; -		addressLow &= (1UL << bit_shift) - 1; -		address |= addressLow; -	} -	if (n >= 1) -		address += options[COMEDI_DEVCONF_AUX_DATA0_LENGTH]; -	if (n >= 2) -		address += options[COMEDI_DEVCONF_AUX_DATA1_LENGTH]; -	if (n >= 3) -		address += options[COMEDI_DEVCONF_AUX_DATA2_LENGTH]; -	BUG_ON(n > 3); -	return (void *)address;  } -int comedi_alloc_subdevice_minor(struct comedi_device *dev, -				 struct comedi_subdevice *s); -void comedi_free_subdevice_minor(struct comedi_subdevice *s); -int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name); -void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -struct usb_device;		/* forward declaration */ -int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name); -void comedi_usb_auto_unconfig(struct usb_device *usbdev); +#endif /* CONFIG_COMEDI_PCI_DRIVERS */ -#ifdef CONFIG_COMEDI_PCI_DRIVERS -#define CONFIG_COMEDI_PCI -#endif -#ifdef CONFIG_COMEDI_PCI_DRIVERS_MODULE -#define CONFIG_COMEDI_PCI -#endif  #ifdef CONFIG_COMEDI_PCMCIA_DRIVERS -#define CONFIG_COMEDI_PCMCIA -#endif -#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS_MODULE -#define CONFIG_COMEDI_PCMCIA -#endif + +/* comedi_pcmcia.c - comedi PCMCIA driver specific functions */ + +struct pcmcia_driver; +struct pcmcia_device; + +struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *); + +int comedi_pcmcia_enable(struct comedi_device *, +			 int (*conf_check)(struct pcmcia_device *, void *)); +void comedi_pcmcia_disable(struct comedi_device *); + +int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *); +void comedi_pcmcia_auto_unconfig(struct pcmcia_device *); + +int comedi_pcmcia_driver_register(struct comedi_driver *, +					struct pcmcia_driver *); +void comedi_pcmcia_driver_unregister(struct comedi_driver *, +					struct pcmcia_driver *); + +/** + * module_comedi_pcmcia_driver() - Helper macro for registering a comedi PCMCIA driver + * @__comedi_driver: comedi_driver struct + * @__pcmcia_driver: pcmcia_driver struct + * + * Helper macro for comedi PCMCIA drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_pcmcia_driver(__comedi_driver, __pcmcia_driver) \ +	module_driver(__comedi_driver, comedi_pcmcia_driver_register, \ +			comedi_pcmcia_driver_unregister, &(__pcmcia_driver)) + +#endif /* CONFIG_COMEDI_PCMCIA_DRIVERS */ + +#ifdef CONFIG_COMEDI_USB_DRIVERS + +/* comedi_usb.c - comedi USB driver specific functions */ + +struct usb_driver; +struct usb_interface; + +struct usb_interface *comedi_to_usb_interface(struct comedi_device *); +struct usb_device *comedi_to_usb_dev(struct comedi_device *); + +int comedi_usb_auto_config(struct usb_interface *, struct comedi_driver *, +			   unsigned long context); +void comedi_usb_auto_unconfig(struct usb_interface *); + +int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *); +void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *); + +/** + * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver + * @__comedi_driver: comedi_driver struct + * @__usb_driver: usb_driver struct + * + * Helper macro for comedi USB drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \ +	module_driver(__comedi_driver, comedi_usb_driver_register, \ +			comedi_usb_driver_unregister, &(__usb_driver)) + +#endif /* CONFIG_COMEDI_USB_DRIVERS */  #endif /* _COMEDIDEV_H */  | 
