/*
 *  module/drivers.c
 *  functions for manipulating drivers
 *
 *  COMEDI - Linux Control and Measurement Device Interface
 *  Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
 *  Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  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.
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/dma-direction.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>

#include "comedidev.h"
#include "comedi_internal.h"

struct comedi_driver *comedi_drivers;
/* protects access to comedi_drivers */
DEFINE_MUTEX(comedi_drivers_list_lock);

/**
 * comedi_set_hw_dev() - Set hardware device associated with COMEDI device
 * @dev: COMEDI device.
 * @hw_dev: Hardware device.
 *
 * For automatically configured COMEDI devices (resulting from a call to
 * comedi_auto_config() or one of its wrappers from the low-level COMEDI
 * driver), comedi_set_hw_dev() is called automatically by the COMEDI core
 * to associate the COMEDI device with the hardware device.  It can also be
 * called directly by "legacy" low-level COMEDI drivers that rely on the
 * %COMEDI_DEVCONFIG ioctl to configure the hardware as long as the hardware
 * has a &struct device.
 *
 * If @dev->hw_dev is NULL, it gets a reference to @hw_dev and sets
 * @dev->hw_dev, otherwise, it does nothing.  Calling it multiple times
 * with the same hardware device is not considered an error.  If it gets
 * a reference to the hardware device, it will be automatically 'put' when
 * the device is detached from COMEDI.
 *
 * Returns 0 if @dev->hw_dev was NULL or the same as @hw_dev, otherwise
 * returns -EEXIST.
 */
int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
{
	if (hw_dev == dev->hw_dev)
		return 0;
	if (dev->hw_dev)
		return -EEXIST;
	dev->hw_dev = get_device(hw_dev);
	return 0;
}
EXPORT_SYMBOL_GPL(comedi_set_hw_dev);

static void comedi_clear_hw_dev(struct comedi_device *dev)
{
	put_device(dev->hw_dev);
	dev->hw_dev = NULL;
}

/**
 * comedi_alloc_devpriv() - Allocate memory for the device private data
 * @dev: COMEDI device.
 * @size: Size of the memory to allocate.
 *
 * The allocated memory is zero-filled.  @dev->private points to it on
 * return.  The memory will be automatically freed when the COMEDI device is
 * "detached".
 *
 * Returns a pointer to the allocated memory, or NULL on failure.
 */
void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size)
{
	dev->private = kzalloc(size, GFP_KERNEL);
	return dev->private;
}
EXPORT_SYMBOL_GPL(comedi_alloc_devpriv);

/**
 * comedi_alloc_subdevices() - Allocate subdevices for COMEDI device
 * @dev: COMEDI device.
 * @num_subdevices: Number of subdevices to allocate.
 *
 * Allocates and initializes an array of &struct comedi_subdevice for the
 * COMEDI device.  If successful, sets @dev->subdevices to point to the
 * first one and @dev->n_subdevices to the number.
 *
 * Returns 0 on success, -EINVAL if @num_subdevices is < 1, or -ENOMEM if
 * failed to allocate the memory.
 */
int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
{
	struct comedi_subdevice *s;
	int i;

	if (num_subdevices < 1)
		return -EINVAL;

	s = kcalloc(num_subdevices, sizeof(*s), GFP_KERNEL);
	if (!s)
		return -ENOMEM;
	dev->subdevices = s;
	dev->n_subdevices = num_subdevices;

	for (i = 0; i < num_subdevices; ++i) {
		s = &dev->subdevices[i];
		s->device = dev;
		s->index = i;
		s->async_dma_dir = DMA_NONE;
		spin_lock_init(&s->spin_lock);
		s->minor = -1;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);

/**
 * comedi_alloc_subdev_readback() - Allocate memory for the subdevice readback
 * @s: COMEDI subdevice.
 *
 * This is called by low-level COMEDI drivers to allocate an array to record
 * the last values written to a subdevice's analog output channels (at least
 * by the %INSN_WRITE instruction), to allow them to be read back by an
 * %INSN_READ instruction.  It also provides a default handler for the
 * %INSN_READ instruction unless one has already been set.
 *
 * On success, @s->readback points to the first element of the array, which
 * is zero-filled.  The low-level driver is responsible for updating its
 * contents.  @s->insn_read will be set to comedi_readback_insn_read()
 * unless it is already non-NULL.
 *
 * Returns 0 on success, -EINVAL if the subdevice has no channels, or
 * -ENOMEM on allocation failure.
 */
int comedi_alloc_subdev_readback(struct comedi_subdevice *s)
{
	if (!s->n_chan)
		return -EINVAL;

	s->readback = kcalloc(s->n_chan, sizeof(*s->readback), GFP_KERNEL);
	if (!s->readback)
		return -ENOMEM;

	if (!s->insn_read)
		s->insn_read = comedi_readback_insn_read;

	return 0;
}
EXPORT_SYMBOL_GPL(comedi_alloc_subdev_readback);

static void comedi_device_detach_cleanup(struct comedi_device *dev)
{
	int i;
	struct comedi_subdevice *s;

	if (dev->subdevices) {
		for (i = 0; i < dev->n_subdevices; i++) {
			s = &dev->subdevices[i];
			if (comedi_can_auto_free_spriv(s))
				kfree(s->private);
			comedi_free_subdevice_minor(s);
			if (s->async) {
				comedi_buf_alloc(dev, s, 0);
				kfree(s->async);
			}
			kfree(s->readback);
		}
		kfree(dev->subdevices);
		dev->subdevices = NULL;
		dev->n_subdevices = 0;
	}
	kfree(dev->private);
	kfree(dev->pacer);
	dev->private = NULL;
	dev->pacer = NULL;
	dev->driver = NULL;
	dev->board_name = NULL;
	dev->board_ptr = NULL;
	dev->mmio = NULL;
	dev->iobase = 0;
	dev->iolen = 0;
	dev->ioenabled = false;
	dev->irq = 0;
	dev->read_subdev = NULL;
	dev->write_subdev = NULL;
	dev->open = NULL;
	dev->close = NULL;
	comedi_clear_hw_dev(dev);
}

void comedi_device_detach(struct comedi_device *dev)
{
	comedi_device_cancel_all(dev);
	down_write(&dev->attach_lock);
	dev->attached = false;
	dev->detach_count++;
	if (dev->driver)
		dev->driver->detach(dev);
	comedi_device_detach_cleanup(dev);
	up_write(&dev->attach_lock);
}

static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
{
	return -EINVAL;
}

int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
	       struct comedi_insn *insn, unsigned int *data)
{
	return -EINVAL;
}

/**
 * comedi_readback_insn_read() - A generic (*insn_read) for subdevice readback.
 * @dev: COMEDI device.
 * @s: COMEDI subdevice.
 * @insn: COMEDI instruction.
 * @data: Pointer to return the readback data.
 *
 * Handles the %INSN_READ instruction for subdevices that use the readback
 * array allocated by comedi_alloc_subdev_readback().  It may be used
 * directly as the subdevice's handler (@s->insn_read) or called via a
 * wrapper.
 *
 * @insn->n is normally 1, which will read a single value.  If higher, the
 * same element of the readback array will be read multiple times.
 *
 * Returns @insn->n on success, or -EINVAL if @s->readback is NULL.
 */
int comedi_readback_insn_read(struct comedi_device *dev,
			      struct comedi_subdevice *s,
			      struct comedi_insn *insn,
			      unsigned int *data)
{
	unsigned int chan = CR_CHAN(insn->chanspec);
	int i;

	if (!s->readback)
		return -EINVAL;

	for (i = 0; i < insn->n; i++)
		data[i] = s->readback[chan];

	return insn->n;
}
EXPORT_SYMBOL_GPL(comedi_readback_insn_read);

/**
 * comedi_timeout() - Busy-wait for a driver condition to occur
 * @dev: COMEDI device.
 * @s: COMEDI subdevice.
 * @insn: COMEDI instruction.
 * @cb: Callback to check for the condition.
 * @context: Private context from the driver.
 *
 * Busy-waits for up to a second (%COMEDI_TIMEOUT_MS) for the condition or
 * some error (other than -EBUSY) to occur.  The parameters @dev, @s, @insn,
 * and @context are passed to the callback function, which returns -EBUSY to
 * continue waiting or some other value to stop waiting (generally 0 if the
 * condition occurred, or some error value).
 *
 * Returns -ETIMEDOUT if timed out, otherwise the return value from the
 * callback function.
 */
int comedi_timeout(struct comedi_device *dev,
		   struct comedi_subdevice *s,
		   struct comedi_insn *insn,
		   int (*cb)(struct comedi_device *dev,
			     struct comedi_subdevice *s,
			     struct comedi_insn *insn,
			     unsigned long context),
		   unsigned long context)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(COMEDI_TIMEOUT_MS);
	int ret;

	while (time_before(jiffies, timeout)) {
		ret = cb(dev, s, insn, context);
		if (ret != -EBUSY)
			return ret;	/* success (0) or non EBUSY errno */
		cpu_relax();
	}
	return -ETIMEDOUT;
}
EXPORT_SYMBOL_GPL(comedi_timeout);

/**
 * comedi_dio_insn_config() - Boilerplate (*insn_config) for DIO subdevices
 * @dev: COMEDI device.
 * @s: COMEDI subdevice.
 * @insn: COMEDI instruction.
 * @data: Instruction parameters and return data.
 * @mask: io_bits mask for grouped channels, or 0 for single channel.
 *
 * If @mask is 0, it is replaced with a single-bit mask corresponding to the
 * channel number specified by @insn->chanspec.  Otherwise, @mask
 * corresponds to a group of channels (which should include the specified
 * channel) that are always configured together as inputs or outputs.
 *
 * Partially handles the %INSN_CONFIG_DIO_INPUT, %INSN_CONFIG_DIO_OUTPUTS,
 * and %INSN_CONFIG_DIO_QUERY instructions.  The first two update
 * @s->io_bits to record the directions of the masked channels.  The last
 * one sets @data[1] to the current direction of the group of channels
 * (%COMEDI_INPUT) or %COMEDI_OUTPUT) as recorded in @s->io_bits.
 *
 * The caller is responsible for updating the DIO direction in the hardware
 * registers if this function returns 0.
 *
 * Returns 0 for a %INSN_CONFIG_DIO_INPUT or %INSN_CONFIG_DIO_OUTPUT
 * instruction, @insn->n (> 0) for a %INSN_CONFIG_DIO_QUERY instruction, or
 * -EINVAL for some other instruction.
 */
int comedi_dio_insn_config(struct comedi_device *dev,
			   struct comedi_subdevice *s,
			   struct comedi_insn *insn,
			   unsigned int *data,
			   unsigned int mask)
{
	unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);

	if (!mask)
		mask = chan_mask;

	switch (data[0]) {
	case INSN_CONFIG_DIO_INPUT:
		s->io_bits &= ~mask;
		break;

	case INSN_CONFIG_DIO_OUTPUT:
		s->io_bits |= mask;
		break;

	case INSN_CONFIG_DIO_QUERY:
		data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
		return insn->n;

	default:
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(comedi_dio_insn_config);

/**
 * comedi_dio_update_state() - Update the internal state of DIO subdevices
 * @s: COMEDI subdevice.
 * @data: The channel mask and bits to update.
 *
 * Updates @s->state which holds the internal state of the outputs for DIO
 * or DO subdevices (up to 32 channels).  @data[0] contains a bit-mask of
 * the channels to be updated.  @data[1] contains a bit-mask of those
 * channels to be set to '1'.  The caller is responsible for updating the
 * outputs in hardware according to @s->state.  As a minimum, the channels
 * in the returned bit-mask need to be updated.
 *
 * Returns @mask with non-existent channels removed.
 */
unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
				     unsigned int *data)
{
	unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1)
						 : 0xffffffff;
	unsigned int mask = data[0] & chanmask;
	unsigned int bits = data[1];

	if (mask) {
		s->state &= ~mask;
		s->state |= (bits & mask);
	}

	return mask;
}
EXPORT_SYMBOL_GPL(comedi_dio_update_state);

/**
 * comedi_bytes_per_scan() - Get length of asynchronous command "scan" in bytes
 * @s: COMEDI subdevice.
 *
 * Determines the overall scan length according to the subdevice type and the
 * number of channels in the scan.
 *
 * For digital input, output or input/output subdevices, samples for
 * multiple channels are assumed to be packed into one or more unsigned
 * short or unsigned int values according to the subdevice's %SDF_LSAMPL
 * flag.  For other types of subdevice, samples are assumed to occupy a
 * whole unsigned short or unsigned int according to the %SDF_LSAMPL flag.
 *
 * Returns the overall scan length in bytes.
 */
unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s)
{
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int num_samples;
	unsigned int bits_per_sample;

	switch (s->type) {
	case COMEDI_SUBD_DI:
	case COMEDI_SUBD_DO:
	case COMEDI_SUBD_DIO:
		bits_per_sample = 8 * comedi_bytes_per_sample(s);
		num_samples = DIV_ROUND_UP(cmd->scan_end_arg, bits_per_sample);
		break;
	default:
		num_samples = cmd->scan_end_arg;
		break;
	}
	return comedi_samples_to_bytes(s, num_samples);
}
EXPORT_SYMBOL_GPL(comedi_bytes_per_scan);

static unsigned int __comedi_nscans_left(struct comedi_subdevice *s,
					 unsigned int nscans)
{
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;

	if (cmd->stop_src == TRIG_COUNT) {
		unsigned int scans_left = 0;

		if (async->scans_done < cmd->stop_arg)
			scans_left = cmd->stop_arg - async->scans_done;

		if (nscans > scans_left)
			nscans = scans_left;
	}
	return nscans;
}

/**
 * comedi_nscans_left() - Return the number of scans left in the command
 * @s: COMEDI subdevice.
 * @nscans: The expected number of scans or 0 for all available scans.
 *
 * If @nscans is 0, it is set to the number of scans available in the
 * async buffer.
 *
 * If the async command has a stop_src of %TRIG_COUNT, the @nscans will be
 * checked against the number of scans remaining to complete the command.
 *
 * The return value will then be either the expected number of scans or the
 * number of scans remaining to complete the command, whichever is fewer.
 */
unsigned int comedi_nscans_left(struct comedi_subdevice *s,
				unsigned int nscans)
{
	if (nscans == 0) {
		unsigned int nbytes = comedi_buf_read_n_available(s);

		nscans = nbytes / comedi_bytes_per_scan(s);
	}
	return __comedi_nscans_left(s, nscans);
}
EXPORT_SYMBOL_GPL(comedi_nscans_left);

/**
 * comedi_nsamples_left() - Return the number of samples left in the command
 * @s: COMEDI subdevice.
 * @nsamples: The expected number of samples.
 *
 * Returns the number of samples remaining to complete the command, or the
 * specified expected number of samples (@nsamples), whichever is fewer.
 */
unsigned int comedi_nsamples_left(struct comedi_subdevice *s,
				  unsigned int nsamples)
{
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;

	if (cmd->stop_src == TRIG_COUNT) {
		unsigned int scans_left = __comedi_nscans_left(s, cmd->stop_arg);
		unsigned int scan_pos =
		    comedi_bytes_to_samples(s, async->scan_progress);
		unsigned long long samples_left = 0;

		if (scans_left) {
			samples_left = ((unsigned long long)scans_left *
					cmd->scan_end_arg) - scan_pos;
		}

		if (samples_left < nsamples)
			nsamples = samples_left;
	}
	return nsamples;
}
EXPORT_SYMBOL_GPL(comedi_nsamples_left);

/**
 * comedi_inc_scan_progress() - Update scan progress in asynchronous command
 * @s: COMEDI subdevice.
 * @num_bytes: Amount of data in bytes to increment scan progress.
 *
 * Increments the scan progress by the number of bytes specified by @num_bytes.
 * If the scan progress reaches or exceeds the scan length in bytes, reduce
 * it modulo the scan length in bytes and set the "end of scan" asynchronous
 * event flag (%COMEDI_CB_EOS) to be processed later.
 */
void comedi_inc_scan_progress(struct comedi_subdevice *s,
			      unsigned int num_bytes)
{
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	unsigned int scan_length = comedi_bytes_per_scan(s);

	/* track the 'cur_chan' for non-SDF_PACKED subdevices */
	if (!(s->subdev_flags & SDF_PACKED)) {
		async->cur_chan += comedi_bytes_to_samples(s, num_bytes);
		async->cur_chan %= cmd->chanlist_len;
	}

	async->scan_progress += num_bytes;
	if (async->scan_progress >= scan_length) {
		unsigned int nscans = async->scan_progress / scan_length;

		if (async->scans_done < (UINT_MAX - nscans))
			async->scans_done += nscans;
		else
			async->scans_done = UINT_MAX;

		async->scan_progress %= scan_length;
		async->events |= COMEDI_CB_EOS;
	}
}
EXPORT_SYMBOL_GPL(comedi_inc_scan_progress);

/**
 * comedi_handle_events() - Handle events and possibly stop acquisition
 * @dev: COMEDI device.
 * @s: COMEDI subdevice.
 *
 * Handles outstanding asynchronous acquisition event flags associated
 * with the subdevice.  Call the subdevice's @s->cancel() handler if the
 * "end of acquisition", "error" or "overflow" event flags are set in order
 * to stop the acquisition at the driver level.
 *
 * Calls comedi_event() to further process the event flags, which may mark
 * the asynchronous command as no longer running, possibly terminated with
 * an error, and may wake up tasks.
 *
 * Return a bit-mask of the handled events.
 */
unsigned int comedi_handle_events(struct comedi_device *dev,
				  struct comedi_subdevice *s)
{
	unsigned int events = s->async->events;

	if (events == 0)
		return events;

	if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel)
		s->cancel(dev, s);

	comedi_event(dev, s);

	return events;
}
EXPORT_SYMBOL_GPL(comedi_handle_events);

static int insn_rw_emulate_bits(struct comedi_device *dev,
				struct comedi_subdevice *s,
				struct comedi_insn *insn,
				unsigned int *data)
{
	struct comedi_insn _insn;
	unsigned int chan = CR_CHAN(insn->chanspec);
	unsigned int base_chan = (chan < 32) ? 0 : chan;
	unsigned int _data[2];
	int ret;

	memset(_data, 0, sizeof(_data));
	memset(&_insn, 0, sizeof(_insn));
	_insn.insn = INSN_BITS;
	_insn.chanspec = base_chan;
	_insn.n = 2;
	_insn.subdev = insn->subdev;

	if (insn->insn == INSN_WRITE) {
		if (!(s->subdev_flags & SDF_WRITABLE))
			return -EINVAL;
		_data[0] = 1 << (chan - base_chan);		    /* mask */
		_data[1] = data[0] ? (1 << (chan - base_chan)) : 0; /* bits */
	}

	ret = s->insn_bits(dev, s, &_insn, _data);
	if (ret < 0)
		return ret;

	if (insn->insn == INSN_READ)
		data[0] = (_data[1] >> (chan - base_chan)) & 1;

	return 1;
}

static int __comedi_device_postconfig_async(struct comedi_device *dev,
					    struct comedi_subdevice *s)
{
	struct comedi_async *async;
	unsigned int buf_size;
	int ret;

	if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) {
		dev_warn(dev->class_dev,
			 "async subdevices must support SDF_CMD_READ or SDF_CMD_WRITE\n");
		return -EINVAL;
	}
	if (!s->do_cmdtest) {
		dev_warn(dev->class_dev,
			 "async subdevices must have a do_cmdtest() function\n");
		return -EINVAL;
	}
	if (!s->cancel)
		dev_warn(dev->class_dev,
			 "async subdevices should have a cancel() function\n");

	async = kzalloc(sizeof(*async), GFP_KERNEL);
	if (!async)
		return -ENOMEM;

	init_waitqueue_head(&async->wait_head);
	s->async = async;

	async->max_bufsize = comedi_default_buf_maxsize_kb * 1024;
	buf_size = comedi_default_buf_size_kb * 1024;
	if (buf_size > async->max_bufsize)
		buf_size = async->max_bufsize;

	if (comedi_buf_alloc(dev, s, buf_size) < 0) {
		dev_warn(dev->class_dev, "Buffer allocation failed\n");
		return -ENOMEM;
	}
	if (s->buf_change) {
		ret = s->buf_change(dev, s);
		if (ret < 0)
			return ret;
	}

	comedi_alloc_subdevice_minor(s);

	return 0;
}

static int __comedi_device_postconfig(struct comedi_device *dev)
{
	struct comedi_subdevice *s;
	int ret;
	int i;

	for (i = 0; i < dev->n_subdevices; i++) {
		s = &dev->subdevices[i];

		if (s->type == COMEDI_SUBD_UNUSED)
			continue;

		if (s->type == COMEDI_SUBD_DO) {
			if (s->n_chan < 32)
				s->io_bits = (1 << s->n_chan) - 1;
			else
				s->io_bits = 0xffffffff;
		}

		if (s->len_chanlist == 0)
			s->len_chanlist = 1;

		if (s->do_cmd) {
			ret = __comedi_device_postconfig_async(dev, s);
			if (ret)
				return ret;
		}

		if (!s->range_table && !s->range_table_list)
			s->range_table = &range_unknown;

		if (!s->insn_read && s->insn_bits)
			s->insn_read = insn_rw_emulate_bits;
		if (!s->insn_write && s->insn_bits)
			s->insn_write = insn_rw_emulate_bits;

		if (!s->insn_read)
			s->insn_read = insn_inval;
		if (!s->insn_write)
			s->insn_write = insn_inval;
		if (!s->insn_bits)
			s->insn_bits = insn_inval;
		if (!s->insn_config)
			s->insn_config = insn_inval;

		if (!s->poll)
			s->poll = poll_invalid;
	}

	return 0;
}

/* do a little post-config cleanup */
static int comedi_device_postconfig(struct comedi_device *dev)
{
	int ret;

	ret = __comedi_device_postconfig(dev);
	if (ret < 0)
		return ret;
	down_write(&dev->attach_lock);
	dev->attached = true;
	up_write(&dev->attach_lock);
	return 0;
}

/*
 * Generic recognize function for drivers that register their supported
 * board names.
 *
 * 'driv->board_name' points to a 'const char *' member within the
 * zeroth element of an array of some private board information
 * structure, say 'struct foo_board' containing a member 'const char
 * *board_name' that is initialized to point to a board name string that
 * is one of the candidates matched against this function's 'name'
 * parameter.
 *
 * 'driv->offset' is the size of the private board information
 * structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is
 * the length of the array of private board information structures.
 *
 * If one of the board names in the array of private board information
 * structures matches the name supplied to this function, the function
 * returns a pointer to the pointer to the board name, otherwise it
 * returns NULL.  The return value ends up in the 'board_ptr' member of
 * a 'struct comedi_device' that the low-level comedi driver's
 * 'attach()' hook can convert to a point to a particular element of its
 * array of private board information structures by subtracting the
 * offset of the member that points to the board name.  (No subtraction
 * is required if the board name pointer is the first member of the
 * private board information structure, which is generally the case.)
 */
static void *comedi_recognize(struct comedi_driver *driv, const char *name)
{
	char **name_ptr = (char **)driv->board_name;
	int i;

	for (i = 0; i < driv->num_names; i++) {
		if (strcmp(*name_ptr, name) == 0)
			return name_ptr;
		name_ptr = (void *)name_ptr + driv->offset;
	}

	return NULL;
}

static void comedi_report_boards(struct comedi_driver *driv)
{
	unsigned int i;
	const char *const *name_ptr;

	pr_info("comedi: valid board names for %s driver are:\n",
		driv->driver_name);

	name_ptr = driv->board_name;
	for (i = 0; i < driv->num_names; i++) {
		pr_info(" %s\n", *name_ptr);
		name_ptr = (const char **)((char *)name_ptr + driv->offset);
	}

	if (driv->num_names == 0)
		pr_info(" %s\n", driv->driver_name);
}

/**
 * comedi_load_firmware() - Request and load firmware for a device
 * @dev: COMEDI device.
 * @device: Hardware device.
 * @name: The name of the firmware image.
 * @cb: Callback to the upload the firmware image.
 * @context: Private context from the driver.
 *
 * Sends a firmware request for the hardware device and waits for it.  Calls
 * the callback function to upload the firmware to the device, them releases
 * the firmware.
 *
 * Returns 0 on success, -EINVAL if @cb is NULL, or a negative error number
 * from the firmware request or the callback function.
 */
int comedi_load_firmware(struct comedi_device *dev,
			 struct device *device,
			 const char *name,
			 int (*cb)(struct comedi_device *dev,
				   const u8 *data, size_t size,
				   unsigned long context),
			 unsigned long context)
{
	const struct firmware *fw;
	int ret;

	if (!cb)
		return -EINVAL;

	ret = request_firmware(&fw, name, device);
	if (ret == 0) {
		ret = cb(dev, fw->data, fw->size, context);
		release_firmware(fw);
	}

	return ret < 0 ? ret : 0;
}
EXPORT_SYMBOL_GPL(comedi_load_firmware);

/**
 * __comedi_request_region() - Request an I/O region for a legacy driver
 * @dev: COMEDI device.
 * @start: Base address of the I/O region.
 * @len: Length of the I/O region.
 *
 * Requests the specified I/O port region which must start at a non-zero
 * address.
 *
 * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
 * fails.
 */
int __comedi_request_region(struct comedi_device *dev,
			    unsigned long start, unsigned long len)
{
	if (!start) {
		dev_warn(dev->class_dev,
			 "%s: a I/O base address must be specified\n",
			 dev->board_name);
		return -EINVAL;
	}

	if (!request_region(start, len, dev->board_name)) {
		dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",
			 dev->board_name, start, len);
		return -EIO;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(__comedi_request_region);

/**
 * comedi_request_region() - Request an I/O region for a legacy driver
 * @dev: COMEDI device.
 * @start: Base address of the I/O region.
 * @len: Length of the I/O region.
 *
 * Requests the specified I/O port region which must start at a non-zero
 * address.
 *
 * On success, @dev->iobase is set to the base address of the region and
 * @dev->iolen is set to its length.
 *
 * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
 * fails.
 */
int comedi_request_region(struct comedi_device *dev,
			  unsigned long start, unsigned long len)
{
	int ret;

	ret = __comedi_request_region(dev, start, len);
	if (ret == 0) {
		dev->iobase = start;
		dev->iolen = len;
	}

	return ret;
}
EXPORT_SYMBOL_GPL(comedi_request_region);

/**
 * comedi_legacy_detach() - A generic (*detach) function for legacy drivers
 * @dev: COMEDI device.
 *
 * This is a simple, generic 'detach' handler for legacy COMEDI devices that
 * just use a single I/O port region and possibly an IRQ and that don't need
 * any special clean-up for their private device or subdevice storage.  It
 * can also be called by a driver-specific 'detach' handler.
 *
 * If @dev->irq is non-zero, the IRQ will be freed.  If @dev->iobase and
 * @dev->iolen are both non-zero, the I/O port region will be released.
 */
void comedi_legacy_detach(struct comedi_device *dev)
{
	if (dev->irq) {
		free_irq(dev->irq, dev);
		dev->irq = 0;
	}
	if (dev->iobase && dev->iolen) {
		release_region(dev->iobase, dev->iolen);
		dev->iobase = 0;
		dev->iolen = 0;
	}
}
EXPORT_SYMBOL_GPL(comedi_legacy_detach);

int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
	struct comedi_driver *driv;
	int ret;

	if (dev->attached)
		return -EBUSY;

	mutex_lock(&comedi_drivers_list_lock);
	for (driv = comedi_drivers; driv; driv = driv->next) {
		if (!try_module_get(driv->module))
			continue;
		if (driv->num_names) {
			dev->board_ptr = comedi_recognize(driv, it->board_name);
			if (dev->board_ptr)
				break;
		} else if (strcmp(driv->driver_name, it->board_name) == 0) {
			break;
		}
		module_put(driv->module);
	}
	if (!driv) {
		/*  recognize has failed if we get here */
		/*  report valid board names before returning error */
		for (driv = comedi_drivers; driv; driv = driv->next) {
			if (!try_module_get(driv->module))
				continue;
			comedi_report_boards(driv);
			module_put(driv->module);
		}
		ret = -EIO;
		goto out;
	}
	if (!driv->attach) {
		/* driver does not support manual configuration */
		dev_warn(dev->class_dev,
			 "driver '%s' does not support attach using comedi_config\n",
			 driv->driver_name);
		module_put(driv->module);
		ret = -EIO;
		goto out;
	}
	dev->driver = driv;
	dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr
					 : dev->driver->driver_name;
	ret = driv->attach(dev, it);
	if (ret >= 0)
		ret = comedi_device_postconfig(dev);
	if (ret < 0) {
		comedi_device_detach(dev);
		module_put(driv->module);
	}
	/* On success, the driver module count has been incremented. */
out:
	mutex_unlock(&comedi_drivers_list_lock);
	return ret;
}

/**
 * comedi_auto_config() - Create a COMEDI device for a hardware device
 * @hardware_device: Hardware device.
 * @driver: COMEDI low-level driver for the hardware device.
 * @context: Driver context for the auto_attach handler.
 *
 * Allocates a new COMEDI device for the hardware device and calls the
 * low-level driver's 'auto_attach' handler to set-up the hardware and
 * allocate the COMEDI subdevices.  Additional "post-configuration" setting
 * up is performed on successful return from the 'auto_attach' handler.
 * If the 'auto_attach' handler fails, the low-level driver's 'detach'
 * handler will be called as part of the clean-up.
 *
 * This is usually called from a wrapper function in a bus-specific COMEDI
 * module, which in turn is usually called from a bus device 'probe'
 * function in the low-level driver.
 *
 * Returns 0 on success, -EINVAL if the parameters are invalid or the
 * post-configuration determines the driver has set the COMEDI device up
 * incorrectly, -ENOMEM if failed to allocate memory, -EBUSY if run out of
 * COMEDI minor device numbers, or some negative error number returned by
 * the driver's 'auto_attach' handler.
 */
int comedi_auto_config(struct device *hardware_device,
		       struct comedi_driver *driver, unsigned long context)
{
	struct comedi_device *dev;
	int ret;

	if (!hardware_device) {
		pr_warn("BUG! comedi_auto_config called with NULL hardware_device\n");
		return -EINVAL;
	}
	if (!driver) {
		dev_warn(hardware_device,
			 "BUG! comedi_auto_config called with NULL comedi driver\n");
		return -EINVAL;
	}

	if (!driver->auto_attach) {
		dev_warn(hardware_device,
			 "BUG! comedi driver '%s' has no auto_attach handler\n",
			 driver->driver_name);
		return -EINVAL;
	}

	dev = comedi_alloc_board_minor(hardware_device);
	if (IS_ERR(dev)) {
		dev_warn(hardware_device,
			 "driver '%s' could not create device.\n",
			 driver->driver_name);
		return PTR_ERR(dev);
	}
	/* Note: comedi_alloc_board_minor() locked dev->mutex. */

	dev->driver = driver;
	dev->board_name = dev->driver->driver_name;
	ret = driver->auto_attach(dev, context);
	if (ret >= 0)
		ret = comedi_device_postconfig(dev);
	mutex_unlock(&dev->mutex);

	if (ret < 0) {
		dev_warn(hardware_device,
			 "driver '%s' failed to auto-configure device.\n",
			 driver->driver_name);
		comedi_release_hardware_device(hardware_device);
	} else {
		/*
		 * class_dev should be set properly here
		 *  after a successful auto config
		 */
		dev_info(dev->class_dev,
			 "driver '%s' has successfully auto-configured '%s'.\n",
			 driver->driver_name, dev->board_name);
	}
	return ret;
}
EXPORT_SYMBOL_GPL(comedi_auto_config);

/**
 * comedi_auto_unconfig() - Unconfigure auto-allocated COMEDI device
 * @hardware_device: Hardware device previously passed to
 *                   comedi_auto_config().
 *
 * Cleans up and eventually destroys the COMEDI device allocated by
 * comedi_auto_config() for the same hardware device.  As part of this
 * clean-up, the low-level COMEDI driver's 'detach' handler will be called.
 * (The COMEDI device itself will persist in an unattached state if it is
 * still open, until it is released, and any mmapped buffers will persist
 * until they are munmapped.)
 *
 * This is usually called from a wrapper module in a bus-specific COMEDI
 * module, which in turn is usually set as the bus device 'remove' function
 * in the low-level COMEDI driver.
 */
void comedi_auto_unconfig(struct device *hardware_device)
{
	if (!hardware_device)
		return;
	comedi_release_hardware_device(hardware_device);
}
EXPORT_SYMBOL_GPL(comedi_auto_unconfig);

/**
 * comedi_driver_register() - Register a low-level COMEDI driver
 * @driver: Low-level COMEDI driver.
 *
 * The low-level COMEDI driver is added to the list of registered COMEDI
 * drivers.  This is used by the handler for the "/proc/comedi" file and is
 * also used by the handler for the %COMEDI_DEVCONFIG ioctl to configure
 * "legacy" COMEDI devices (for those low-level drivers that support it).
 *
 * Returns 0.
 */
int comedi_driver_register(struct comedi_driver *driver)
{
	mutex_lock(&comedi_drivers_list_lock);
	driver->next = comedi_drivers;
	comedi_drivers = driver;
	mutex_unlock(&comedi_drivers_list_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(comedi_driver_register);

/**
 * comedi_driver_unregister() - Unregister a low-level COMEDI driver
 * @driver: Low-level COMEDI driver.
 *
 * The low-level COMEDI driver is removed from the list of registered COMEDI
 * drivers.  Detaches any COMEDI devices attached to the driver, which will
 * result in the low-level driver's 'detach' handler being called for those
 * devices before this function returns.
 */
void comedi_driver_unregister(struct comedi_driver *driver)
{
	struct comedi_driver *prev;
	int i;

	/* unlink the driver */
	mutex_lock(&comedi_drivers_list_lock);
	if (comedi_drivers == driver) {
		comedi_drivers = driver->next;
	} else {
		for (prev = comedi_drivers; prev->next; prev = prev->next) {
			if (prev->next == driver) {
				prev->next = driver->next;
				break;
			}
		}
	}
	mutex_unlock(&comedi_drivers_list_lock);

	/* check for devices using this driver */
	for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
		struct comedi_device *dev = comedi_dev_get_from_minor(i);

		if (!dev)
			continue;

		mutex_lock(&dev->mutex);
		if (dev->attached && dev->driver == driver) {
			if (dev->use_count)
				dev_warn(dev->class_dev,
					 "BUG! detaching device with use_count=%d\n",
					 dev->use_count);
			comedi_device_detach(dev);
		}
		mutex_unlock(&dev->mutex);
		comedi_dev_put(dev);
	}
}
EXPORT_SYMBOL_GPL(comedi_driver_unregister);
