// SPDX-License-Identifier: GPL-2.0+1/*2* module/drivers.c3* functions for manipulating drivers4*5* COMEDI - Linux Control and Measurement Device Interface6* Copyright (C) 1997-2000 David A. Schleef <[email protected]>7* Copyright (C) 2002 Frank Mori Hess <[email protected]>8*/910#include <linux/device.h>11#include <linux/module.h>12#include <linux/errno.h>13#include <linux/kernel.h>14#include <linux/ioport.h>15#include <linux/slab.h>16#include <linux/dma-direction.h>17#include <linux/interrupt.h>18#include <linux/firmware.h>19#include <linux/comedi/comedidev.h>20#include "comedi_internal.h"2122struct comedi_driver *comedi_drivers;23/* protects access to comedi_drivers */24DEFINE_MUTEX(comedi_drivers_list_lock);2526/**27* comedi_set_hw_dev() - Set hardware device associated with COMEDI device28* @dev: COMEDI device.29* @hw_dev: Hardware device.30*31* For automatically configured COMEDI devices (resulting from a call to32* comedi_auto_config() or one of its wrappers from the low-level COMEDI33* driver), comedi_set_hw_dev() is called automatically by the COMEDI core34* to associate the COMEDI device with the hardware device. It can also be35* called directly by "legacy" low-level COMEDI drivers that rely on the36* %COMEDI_DEVCONFIG ioctl to configure the hardware as long as the hardware37* has a &struct device.38*39* If @dev->hw_dev is NULL, it gets a reference to @hw_dev and sets40* @dev->hw_dev, otherwise, it does nothing. Calling it multiple times41* with the same hardware device is not considered an error. If it gets42* a reference to the hardware device, it will be automatically 'put' when43* the device is detached from COMEDI.44*45* Returns 0 if @dev->hw_dev was NULL or the same as @hw_dev, otherwise46* returns -EEXIST.47*/48int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)49{50if (hw_dev == dev->hw_dev)51return 0;52if (dev->hw_dev)53return -EEXIST;54dev->hw_dev = get_device(hw_dev);55return 0;56}57EXPORT_SYMBOL_GPL(comedi_set_hw_dev);5859static void comedi_clear_hw_dev(struct comedi_device *dev)60{61put_device(dev->hw_dev);62dev->hw_dev = NULL;63}6465/**66* comedi_alloc_devpriv() - Allocate memory for the device private data67* @dev: COMEDI device.68* @size: Size of the memory to allocate.69*70* The allocated memory is zero-filled. @dev->private points to it on71* return. The memory will be automatically freed when the COMEDI device is72* "detached".73*74* Returns a pointer to the allocated memory, or NULL on failure.75*/76void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size)77{78dev->private = kzalloc(size, GFP_KERNEL);79return dev->private;80}81EXPORT_SYMBOL_GPL(comedi_alloc_devpriv);8283/**84* comedi_alloc_subdevices() - Allocate subdevices for COMEDI device85* @dev: COMEDI device.86* @num_subdevices: Number of subdevices to allocate.87*88* Allocates and initializes an array of &struct comedi_subdevice for the89* COMEDI device. If successful, sets @dev->subdevices to point to the90* first one and @dev->n_subdevices to the number.91*92* Returns 0 on success, -EINVAL if @num_subdevices is < 1, or -ENOMEM if93* failed to allocate the memory.94*/95int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)96{97struct comedi_subdevice *s;98int i;99100if (num_subdevices < 1)101return -EINVAL;102103s = kcalloc(num_subdevices, sizeof(*s), GFP_KERNEL);104if (!s)105return -ENOMEM;106dev->subdevices = s;107dev->n_subdevices = num_subdevices;108109for (i = 0; i < num_subdevices; ++i) {110s = &dev->subdevices[i];111s->device = dev;112s->index = i;113s->async_dma_dir = DMA_NONE;114spin_lock_init(&s->spin_lock);115s->minor = -1;116}117return 0;118}119EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);120121/**122* comedi_alloc_subdev_readback() - Allocate memory for the subdevice readback123* @s: COMEDI subdevice.124*125* This is called by low-level COMEDI drivers to allocate an array to record126* the last values written to a subdevice's analog output channels (at least127* by the %INSN_WRITE instruction), to allow them to be read back by an128* %INSN_READ instruction. It also provides a default handler for the129* %INSN_READ instruction unless one has already been set.130*131* On success, @s->readback points to the first element of the array, which132* is zero-filled. The low-level driver is responsible for updating its133* contents. @s->insn_read will be set to comedi_readback_insn_read()134* unless it is already non-NULL.135*136* Returns 0 on success, -EINVAL if the subdevice has no channels, or137* -ENOMEM on allocation failure.138*/139int comedi_alloc_subdev_readback(struct comedi_subdevice *s)140{141if (!s->n_chan)142return -EINVAL;143144s->readback = kcalloc(s->n_chan, sizeof(*s->readback), GFP_KERNEL);145if (!s->readback)146return -ENOMEM;147148if (!s->insn_read)149s->insn_read = comedi_readback_insn_read;150151return 0;152}153EXPORT_SYMBOL_GPL(comedi_alloc_subdev_readback);154155static void comedi_device_detach_cleanup(struct comedi_device *dev)156{157int i;158struct comedi_subdevice *s;159160lockdep_assert_held_write(&dev->attach_lock);161lockdep_assert_held(&dev->mutex);162if (dev->subdevices) {163for (i = 0; i < dev->n_subdevices; i++) {164s = &dev->subdevices[i];165if (comedi_can_auto_free_spriv(s))166kfree(s->private);167comedi_free_subdevice_minor(s);168if (s->async) {169comedi_buf_alloc(dev, s, 0);170kfree(s->async);171}172kfree(s->readback);173}174kfree(dev->subdevices);175dev->subdevices = NULL;176dev->n_subdevices = 0;177}178kfree(dev->private);179if (!IS_ERR(dev->pacer))180kfree(dev->pacer);181dev->private = NULL;182dev->pacer = NULL;183dev->driver = NULL;184dev->board_name = NULL;185dev->board_ptr = NULL;186dev->mmio = NULL;187dev->iobase = 0;188dev->iolen = 0;189dev->ioenabled = false;190dev->irq = 0;191dev->read_subdev = NULL;192dev->write_subdev = NULL;193dev->open = NULL;194dev->close = NULL;195comedi_clear_hw_dev(dev);196}197198void comedi_device_detach_locked(struct comedi_device *dev)199{200lockdep_assert_held_write(&dev->attach_lock);201lockdep_assert_held(&dev->mutex);202comedi_device_cancel_all(dev);203dev->attached = false;204dev->detach_count++;205if (dev->driver)206dev->driver->detach(dev);207comedi_device_detach_cleanup(dev);208}209210void comedi_device_detach(struct comedi_device *dev)211{212lockdep_assert_held(&dev->mutex);213down_write(&dev->attach_lock);214comedi_device_detach_locked(dev);215up_write(&dev->attach_lock);216}217218static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)219{220return -EINVAL;221}222223static int insn_device_inval(struct comedi_device *dev,224struct comedi_insn *insn, unsigned int *data)225{226return -EINVAL;227}228229static unsigned int get_zero_valid_routes(struct comedi_device *dev,230unsigned int n_pairs,231unsigned int *pair_data)232{233return 0;234}235236int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,237struct comedi_insn *insn, unsigned int *data)238{239return -EINVAL;240}241242/**243* comedi_readback_insn_read() - A generic (*insn_read) for subdevice readback.244* @dev: COMEDI device.245* @s: COMEDI subdevice.246* @insn: COMEDI instruction.247* @data: Pointer to return the readback data.248*249* Handles the %INSN_READ instruction for subdevices that use the readback250* array allocated by comedi_alloc_subdev_readback(). It may be used251* directly as the subdevice's handler (@s->insn_read) or called via a252* wrapper.253*254* @insn->n is normally 1, which will read a single value. If higher, the255* same element of the readback array will be read multiple times.256*257* Returns @insn->n on success, or -EINVAL if @s->readback is NULL.258*/259int comedi_readback_insn_read(struct comedi_device *dev,260struct comedi_subdevice *s,261struct comedi_insn *insn,262unsigned int *data)263{264unsigned int chan = CR_CHAN(insn->chanspec);265int i;266267if (!s->readback)268return -EINVAL;269270for (i = 0; i < insn->n; i++)271data[i] = s->readback[chan];272273return insn->n;274}275EXPORT_SYMBOL_GPL(comedi_readback_insn_read);276277/**278* comedi_timeout() - Busy-wait for a driver condition to occur279* @dev: COMEDI device.280* @s: COMEDI subdevice.281* @insn: COMEDI instruction.282* @cb: Callback to check for the condition.283* @context: Private context from the driver.284*285* Busy-waits for up to a second (%COMEDI_TIMEOUT_MS) for the condition or286* some error (other than -EBUSY) to occur. The parameters @dev, @s, @insn,287* and @context are passed to the callback function, which returns -EBUSY to288* continue waiting or some other value to stop waiting (generally 0 if the289* condition occurred, or some error value).290*291* Returns -ETIMEDOUT if timed out, otherwise the return value from the292* callback function.293*/294int comedi_timeout(struct comedi_device *dev,295struct comedi_subdevice *s,296struct comedi_insn *insn,297int (*cb)(struct comedi_device *dev,298struct comedi_subdevice *s,299struct comedi_insn *insn,300unsigned long context),301unsigned long context)302{303unsigned long timeout = jiffies + msecs_to_jiffies(COMEDI_TIMEOUT_MS);304int ret;305306while (time_before(jiffies, timeout)) {307ret = cb(dev, s, insn, context);308if (ret != -EBUSY)309return ret; /* success (0) or non EBUSY errno */310cpu_relax();311}312return -ETIMEDOUT;313}314EXPORT_SYMBOL_GPL(comedi_timeout);315316/**317* comedi_dio_insn_config() - Boilerplate (*insn_config) for DIO subdevices318* @dev: COMEDI device.319* @s: COMEDI subdevice.320* @insn: COMEDI instruction.321* @data: Instruction parameters and return data.322* @mask: io_bits mask for grouped channels, or 0 for single channel.323*324* If @mask is 0, it is replaced with a single-bit mask corresponding to the325* channel number specified by @insn->chanspec. Otherwise, @mask326* corresponds to a group of channels (which should include the specified327* channel) that are always configured together as inputs or outputs.328*329* Partially handles the %INSN_CONFIG_DIO_INPUT, %INSN_CONFIG_DIO_OUTPUTS,330* and %INSN_CONFIG_DIO_QUERY instructions. The first two update331* @s->io_bits to record the directions of the masked channels. The last332* one sets @data[1] to the current direction of the group of channels333* (%COMEDI_INPUT) or %COMEDI_OUTPUT) as recorded in @s->io_bits.334*335* The caller is responsible for updating the DIO direction in the hardware336* registers if this function returns 0.337*338* Returns 0 for a %INSN_CONFIG_DIO_INPUT or %INSN_CONFIG_DIO_OUTPUT339* instruction, @insn->n (> 0) for a %INSN_CONFIG_DIO_QUERY instruction, or340* -EINVAL for some other instruction.341*/342int comedi_dio_insn_config(struct comedi_device *dev,343struct comedi_subdevice *s,344struct comedi_insn *insn,345unsigned int *data,346unsigned int mask)347{348unsigned int chan = CR_CHAN(insn->chanspec);349350if (!mask && chan < 32)351mask = 1U << chan;352353switch (data[0]) {354case INSN_CONFIG_DIO_INPUT:355s->io_bits &= ~mask;356break;357358case INSN_CONFIG_DIO_OUTPUT:359s->io_bits |= mask;360break;361362case INSN_CONFIG_DIO_QUERY:363data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;364return insn->n;365366default:367return -EINVAL;368}369370return 0;371}372EXPORT_SYMBOL_GPL(comedi_dio_insn_config);373374/**375* comedi_dio_update_state() - Update the internal state of DIO subdevices376* @s: COMEDI subdevice.377* @data: The channel mask and bits to update.378*379* Updates @s->state which holds the internal state of the outputs for DIO380* or DO subdevices (up to 32 channels). @data[0] contains a bit-mask of381* the channels to be updated. @data[1] contains a bit-mask of those382* channels to be set to '1'. The caller is responsible for updating the383* outputs in hardware according to @s->state. As a minimum, the channels384* in the returned bit-mask need to be updated.385*386* Returns @mask with non-existent channels removed.387*/388unsigned int comedi_dio_update_state(struct comedi_subdevice *s,389unsigned int *data)390{391unsigned int chanmask = (s->n_chan < 32) ? ((1U << s->n_chan) - 1)392: 0xffffffff;393unsigned int mask = data[0] & chanmask;394unsigned int bits = data[1];395396if (mask) {397s->state &= ~mask;398s->state |= (bits & mask);399}400401return mask;402}403EXPORT_SYMBOL_GPL(comedi_dio_update_state);404405/**406* comedi_bytes_per_scan_cmd() - Get length of asynchronous command "scan" in407* bytes408* @s: COMEDI subdevice.409* @cmd: COMEDI command.410*411* Determines the overall scan length according to the subdevice type and the412* number of channels in the scan for the specified command.413*414* For digital input, output or input/output subdevices, samples for415* multiple channels are assumed to be packed into one or more unsigned416* short or unsigned int values according to the subdevice's %SDF_LSAMPL417* flag. For other types of subdevice, samples are assumed to occupy a418* whole unsigned short or unsigned int according to the %SDF_LSAMPL flag.419*420* Returns the overall scan length in bytes.421*/422unsigned int comedi_bytes_per_scan_cmd(struct comedi_subdevice *s,423struct comedi_cmd *cmd)424{425unsigned int num_samples;426unsigned int bits_per_sample;427428switch (s->type) {429case COMEDI_SUBD_DI:430case COMEDI_SUBD_DO:431case COMEDI_SUBD_DIO:432bits_per_sample = 8 * comedi_bytes_per_sample(s);433num_samples = DIV_ROUND_UP(cmd->scan_end_arg, bits_per_sample);434break;435default:436num_samples = cmd->scan_end_arg;437break;438}439return comedi_samples_to_bytes(s, num_samples);440}441EXPORT_SYMBOL_GPL(comedi_bytes_per_scan_cmd);442443static unsigned int _comedi_bytes_per_scan(struct comedi_subdevice *s)444{445struct comedi_cmd *cmd = &s->async->cmd;446447return comedi_bytes_per_scan_cmd(s, cmd);448}449450/**451* comedi_bytes_per_scan() - Get length of asynchronous command "scan" in bytes452* @s: COMEDI subdevice.453*454* Determines the overall scan length according to the subdevice type and the455* number of channels in the scan for the current command.456*457* For digital input, output or input/output subdevices, samples for458* multiple channels are assumed to be packed into one or more unsigned459* short or unsigned int values according to the subdevice's %SDF_LSAMPL460* flag. For other types of subdevice, samples are assumed to occupy a461* whole unsigned short or unsigned int according to the %SDF_LSAMPL flag.462*463* Returns the overall scan length in bytes.464*/465unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s)466{467unsigned int num_bytes;468469if (comedi_get_is_subdevice_running(s)) {470num_bytes = _comedi_bytes_per_scan(s);471comedi_put_is_subdevice_running(s);472} else {473/* Use nomimal, single sample scan length. */474num_bytes = comedi_samples_to_bytes(s, 1);475}476return num_bytes;477}478EXPORT_SYMBOL_GPL(comedi_bytes_per_scan);479480static unsigned int __comedi_nscans_left(struct comedi_subdevice *s,481unsigned int nscans)482{483struct comedi_async *async = s->async;484struct comedi_cmd *cmd = &async->cmd;485486if (cmd->stop_src == TRIG_COUNT) {487unsigned int scans_left = 0;488489if (async->scans_done < cmd->stop_arg)490scans_left = cmd->stop_arg - async->scans_done;491492if (nscans > scans_left)493nscans = scans_left;494}495return nscans;496}497498static unsigned int _comedi_nscans_left(struct comedi_subdevice *s,499unsigned int nscans)500{501if (nscans == 0) {502unsigned int nbytes = _comedi_buf_read_n_available(s);503504nscans = nbytes / _comedi_bytes_per_scan(s);505}506return __comedi_nscans_left(s, nscans);507}508509/**510* comedi_nscans_left() - Return the number of scans left in the command511* @s: COMEDI subdevice.512* @nscans: The expected number of scans or 0 for all available scans.513*514* If @nscans is 0, it is set to the number of scans available in the515* async buffer.516*517* If the async command has a stop_src of %TRIG_COUNT, the @nscans will be518* checked against the number of scans remaining to complete the command.519*520* The return value will then be either the expected number of scans or the521* number of scans remaining to complete the command, whichever is fewer.522*/523unsigned int comedi_nscans_left(struct comedi_subdevice *s,524unsigned int nscans)525{526if (comedi_get_is_subdevice_running(s)) {527nscans = _comedi_nscans_left(s, nscans);528comedi_put_is_subdevice_running(s);529} else {530nscans = 0;531}532return nscans;533}534EXPORT_SYMBOL_GPL(comedi_nscans_left);535536static unsigned int _comedi_nsamples_left(struct comedi_subdevice *s,537unsigned int nsamples)538{539struct comedi_async *async = s->async;540struct comedi_cmd *cmd = &async->cmd;541unsigned long long scans_left;542unsigned long long samples_left;543544if (cmd->stop_src != TRIG_COUNT)545return nsamples;546547scans_left = __comedi_nscans_left(s, cmd->stop_arg);548if (!scans_left)549return 0;550551samples_left = scans_left * cmd->scan_end_arg -552comedi_bytes_to_samples(s, async->scan_progress);553554if (samples_left < nsamples)555return samples_left;556return nsamples;557}558559/**560* comedi_nsamples_left() - Return the number of samples left in the command561* @s: COMEDI subdevice.562* @nsamples: The expected number of samples.563*564* Returns the number of samples remaining to complete the command, or the565* specified expected number of samples (@nsamples), whichever is fewer.566*/567unsigned int comedi_nsamples_left(struct comedi_subdevice *s,568unsigned int nsamples)569{570if (comedi_get_is_subdevice_running(s)) {571nsamples = _comedi_nsamples_left(s, nsamples);572comedi_put_is_subdevice_running(s);573} else {574nsamples = 0;575}576return nsamples;577}578EXPORT_SYMBOL_GPL(comedi_nsamples_left);579580void _comedi_inc_scan_progress(struct comedi_subdevice *s,581unsigned int num_bytes)582{583struct comedi_async *async = s->async;584struct comedi_cmd *cmd = &async->cmd;585unsigned int scan_length = _comedi_bytes_per_scan(s);586587/* track the 'cur_chan' for non-SDF_PACKED subdevices */588if (!(s->subdev_flags & SDF_PACKED)) {589async->cur_chan += comedi_bytes_to_samples(s, num_bytes);590async->cur_chan %= cmd->chanlist_len;591}592593async->scan_progress += num_bytes;594if (async->scan_progress >= scan_length) {595unsigned int nscans = async->scan_progress / scan_length;596597if (async->scans_done < (UINT_MAX - nscans))598async->scans_done += nscans;599else600async->scans_done = UINT_MAX;601602async->scan_progress %= scan_length;603async->events |= COMEDI_CB_EOS;604}605}606607/**608* comedi_inc_scan_progress() - Update scan progress in asynchronous command609* @s: COMEDI subdevice.610* @num_bytes: Amount of data in bytes to increment scan progress.611*612* Increments the scan progress by the number of bytes specified by @num_bytes.613* If the scan progress reaches or exceeds the scan length in bytes, reduce614* it modulo the scan length in bytes and set the "end of scan" asynchronous615* event flag (%COMEDI_CB_EOS) to be processed later.616*/617void comedi_inc_scan_progress(struct comedi_subdevice *s,618unsigned int num_bytes)619{620if (comedi_get_is_subdevice_running(s)) {621_comedi_inc_scan_progress(s, num_bytes);622comedi_put_is_subdevice_running(s);623}624}625EXPORT_SYMBOL_GPL(comedi_inc_scan_progress);626627static unsigned int _comedi_handle_events(struct comedi_device *dev,628struct comedi_subdevice *s)629{630unsigned int events = s->async->events;631632if (events == 0)633return events;634635if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel)636s->cancel(dev, s);637638_comedi_event(dev, s);639640return events;641}642643/**644* comedi_handle_events() - Handle events and possibly stop acquisition645* @dev: COMEDI device.646* @s: COMEDI subdevice.647*648* Handles outstanding asynchronous acquisition event flags associated649* with the subdevice. Call the subdevice's @s->cancel() handler if the650* "end of acquisition", "error" or "overflow" event flags are set in order651* to stop the acquisition at the driver level.652*653* Calls comedi_event() to further process the event flags, which may mark654* the asynchronous command as no longer running, possibly terminated with655* an error, and may wake up tasks.656*657* Return a bit-mask of the handled events.658*/659unsigned int comedi_handle_events(struct comedi_device *dev,660struct comedi_subdevice *s)661{662unsigned int events;663664if (comedi_get_is_subdevice_running(s)) {665events = _comedi_handle_events(dev, s);666comedi_put_is_subdevice_running(s);667} else {668events = 0;669}670return events;671}672EXPORT_SYMBOL_GPL(comedi_handle_events);673674static int insn_rw_emulate_bits(struct comedi_device *dev,675struct comedi_subdevice *s,676struct comedi_insn *insn,677unsigned int *data)678{679struct comedi_insn _insn;680unsigned int chan = CR_CHAN(insn->chanspec);681unsigned int base_chan = (chan < 32) ? 0 : chan;682unsigned int _data[2];683unsigned int i;684int ret;685686memset(_data, 0, sizeof(_data));687memset(&_insn, 0, sizeof(_insn));688_insn.insn = INSN_BITS;689_insn.chanspec = base_chan;690_insn.n = 2;691_insn.subdev = insn->subdev;692693if (insn->insn == INSN_WRITE) {694if (!(s->subdev_flags & SDF_WRITABLE))695return -EINVAL;696_data[0] = 1U << (chan - base_chan); /* mask */697}698for (i = 0; i < insn->n; i++) {699if (insn->insn == INSN_WRITE)700_data[1] = data[i] ? _data[0] : 0; /* bits */701702ret = s->insn_bits(dev, s, &_insn, _data);703if (ret < 0)704return ret;705706if (insn->insn == INSN_READ)707data[i] = (_data[1] >> (chan - base_chan)) & 1;708}709710return insn->n;711}712713static int __comedi_device_postconfig_async(struct comedi_device *dev,714struct comedi_subdevice *s)715{716struct comedi_async *async;717unsigned int buf_size;718int ret;719720lockdep_assert_held(&dev->mutex);721if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) {722dev_warn(dev->class_dev,723"async subdevices must support SDF_CMD_READ or SDF_CMD_WRITE\n");724return -EINVAL;725}726if (!s->do_cmdtest) {727dev_warn(dev->class_dev,728"async subdevices must have a do_cmdtest() function\n");729return -EINVAL;730}731if (!s->cancel)732dev_warn(dev->class_dev,733"async subdevices should have a cancel() function\n");734735async = kzalloc(sizeof(*async), GFP_KERNEL);736if (!async)737return -ENOMEM;738739init_waitqueue_head(&async->wait_head);740init_completion(&async->run_complete);741s->async = async;742743async->max_bufsize = comedi_default_buf_maxsize_kb * 1024;744buf_size = comedi_default_buf_size_kb * 1024;745if (buf_size > async->max_bufsize)746buf_size = async->max_bufsize;747748if (comedi_buf_alloc(dev, s, buf_size) < 0) {749dev_warn(dev->class_dev, "Buffer allocation failed\n");750return -ENOMEM;751}752if (s->buf_change) {753ret = s->buf_change(dev, s);754if (ret < 0)755return ret;756}757758comedi_alloc_subdevice_minor(s);759760return 0;761}762763static int __comedi_device_postconfig(struct comedi_device *dev)764{765struct comedi_subdevice *s;766int ret;767int i;768769lockdep_assert_held(&dev->mutex);770if (!dev->insn_device_config)771dev->insn_device_config = insn_device_inval;772773if (!dev->get_valid_routes)774dev->get_valid_routes = get_zero_valid_routes;775776for (i = 0; i < dev->n_subdevices; i++) {777s = &dev->subdevices[i];778779if (s->type == COMEDI_SUBD_UNUSED)780continue;781782if (s->type == COMEDI_SUBD_DO) {783if (s->n_chan < 32)784s->io_bits = (1U << s->n_chan) - 1;785else786s->io_bits = 0xffffffff;787}788789if (s->len_chanlist == 0)790s->len_chanlist = 1;791792if (s->do_cmd) {793ret = __comedi_device_postconfig_async(dev, s);794if (ret)795return ret;796}797798if (!s->range_table && !s->range_table_list)799s->range_table = &range_unknown;800801if (!s->insn_read && s->insn_bits)802s->insn_read = insn_rw_emulate_bits;803if (!s->insn_write && s->insn_bits)804s->insn_write = insn_rw_emulate_bits;805806if (!s->insn_read)807s->insn_read = insn_inval;808if (!s->insn_write)809s->insn_write = insn_inval;810if (!s->insn_bits)811s->insn_bits = insn_inval;812if (!s->insn_config)813s->insn_config = insn_inval;814815if (!s->poll)816s->poll = poll_invalid;817}818819return 0;820}821822/* do a little post-config cleanup */823static int comedi_device_postconfig(struct comedi_device *dev)824{825int ret;826827lockdep_assert_held(&dev->mutex);828ret = __comedi_device_postconfig(dev);829if (ret < 0)830return ret;831down_write(&dev->attach_lock);832dev->attached = true;833up_write(&dev->attach_lock);834return 0;835}836837/*838* Generic recognize function for drivers that register their supported839* board names.840*841* 'driv->board_name' points to a 'const char *' member within the842* zeroth element of an array of some private board information843* structure, say 'struct foo_board' containing a member 'const char844* *board_name' that is initialized to point to a board name string that845* is one of the candidates matched against this function's 'name'846* parameter.847*848* 'driv->offset' is the size of the private board information849* structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is850* the length of the array of private board information structures.851*852* If one of the board names in the array of private board information853* structures matches the name supplied to this function, the function854* returns a pointer to the pointer to the board name, otherwise it855* returns NULL. The return value ends up in the 'board_ptr' member of856* a 'struct comedi_device' that the low-level comedi driver's857* 'attach()' hook can convert to a point to a particular element of its858* array of private board information structures by subtracting the859* offset of the member that points to the board name. (No subtraction860* is required if the board name pointer is the first member of the861* private board information structure, which is generally the case.)862*/863static void *comedi_recognize(struct comedi_driver *driv, const char *name)864{865char **name_ptr = (char **)driv->board_name;866int i;867868for (i = 0; i < driv->num_names; i++) {869if (strcmp(*name_ptr, name) == 0)870return name_ptr;871name_ptr = (void *)name_ptr + driv->offset;872}873874return NULL;875}876877static void comedi_report_boards(struct comedi_driver *driv)878{879unsigned int i;880const char *const *name_ptr;881882pr_info("comedi: valid board names for %s driver are:\n",883driv->driver_name);884885name_ptr = driv->board_name;886for (i = 0; i < driv->num_names; i++) {887pr_info(" %s\n", *name_ptr);888name_ptr = (const char **)((char *)name_ptr + driv->offset);889}890891if (driv->num_names == 0)892pr_info(" %s\n", driv->driver_name);893}894895/**896* comedi_load_firmware() - Request and load firmware for a device897* @dev: COMEDI device.898* @device: Hardware device.899* @name: The name of the firmware image.900* @cb: Callback to the upload the firmware image.901* @context: Private context from the driver.902*903* Sends a firmware request for the hardware device and waits for it. Calls904* the callback function to upload the firmware to the device, them releases905* the firmware.906*907* Returns 0 on success, -EINVAL if @cb is NULL, or a negative error number908* from the firmware request or the callback function.909*/910int comedi_load_firmware(struct comedi_device *dev,911struct device *device,912const char *name,913int (*cb)(struct comedi_device *dev,914const u8 *data, size_t size,915unsigned long context),916unsigned long context)917{918const struct firmware *fw;919int ret;920921if (!cb)922return -EINVAL;923924ret = request_firmware(&fw, name, device);925if (ret == 0) {926ret = cb(dev, fw->data, fw->size, context);927release_firmware(fw);928}929930return min(ret, 0);931}932EXPORT_SYMBOL_GPL(comedi_load_firmware);933934/**935* __comedi_request_region() - Request an I/O region for a legacy driver936* @dev: COMEDI device.937* @start: Base address of the I/O region.938* @len: Length of the I/O region.939*940* Requests the specified I/O port region which must start at a non-zero941* address.942*943* Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request944* fails.945*/946int __comedi_request_region(struct comedi_device *dev,947unsigned long start, unsigned long len)948{949if (!start) {950dev_warn(dev->class_dev,951"%s: a I/O base address must be specified\n",952dev->board_name);953return -EINVAL;954}955956if (!request_region(start, len, dev->board_name)) {957dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",958dev->board_name, start, len);959return -EIO;960}961962return 0;963}964EXPORT_SYMBOL_GPL(__comedi_request_region);965966/**967* comedi_request_region() - Request an I/O region for a legacy driver968* @dev: COMEDI device.969* @start: Base address of the I/O region.970* @len: Length of the I/O region.971*972* Requests the specified I/O port region which must start at a non-zero973* address.974*975* On success, @dev->iobase is set to the base address of the region and976* @dev->iolen is set to its length.977*978* Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request979* fails.980*/981int comedi_request_region(struct comedi_device *dev,982unsigned long start, unsigned long len)983{984int ret;985986ret = __comedi_request_region(dev, start, len);987if (ret == 0) {988dev->iobase = start;989dev->iolen = len;990}991992return ret;993}994EXPORT_SYMBOL_GPL(comedi_request_region);995996/**997* comedi_legacy_detach() - A generic (*detach) function for legacy drivers998* @dev: COMEDI device.999*1000* This is a simple, generic 'detach' handler for legacy COMEDI devices that1001* just use a single I/O port region and possibly an IRQ and that don't need1002* any special clean-up for their private device or subdevice storage. It1003* can also be called by a driver-specific 'detach' handler.1004*1005* If @dev->irq is non-zero, the IRQ will be freed. If @dev->iobase and1006* @dev->iolen are both non-zero, the I/O port region will be released.1007*/1008void comedi_legacy_detach(struct comedi_device *dev)1009{1010if (dev->irq) {1011free_irq(dev->irq, dev);1012dev->irq = 0;1013}1014if (dev->iobase && dev->iolen) {1015release_region(dev->iobase, dev->iolen);1016dev->iobase = 0;1017dev->iolen = 0;1018}1019}1020EXPORT_SYMBOL_GPL(comedi_legacy_detach);10211022int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)1023{1024struct comedi_driver *driv;1025int ret;10261027lockdep_assert_held(&dev->mutex);1028if (dev->attached)1029return -EBUSY;10301031mutex_lock(&comedi_drivers_list_lock);1032for (driv = comedi_drivers; driv; driv = driv->next) {1033if (!try_module_get(driv->module))1034continue;1035if (driv->num_names) {1036dev->board_ptr = comedi_recognize(driv, it->board_name);1037if (dev->board_ptr)1038break;1039} else if (strcmp(driv->driver_name, it->board_name) == 0) {1040break;1041}1042module_put(driv->module);1043}1044if (!driv) {1045/* recognize has failed if we get here */1046/* report valid board names before returning error */1047for (driv = comedi_drivers; driv; driv = driv->next) {1048if (!try_module_get(driv->module))1049continue;1050comedi_report_boards(driv);1051module_put(driv->module);1052}1053ret = -EIO;1054goto out;1055}1056if (!driv->attach) {1057/* driver does not support manual configuration */1058dev_warn(dev->class_dev,1059"driver '%s' does not support attach using comedi_config\n",1060driv->driver_name);1061module_put(driv->module);1062ret = -EIO;1063goto out;1064}1065dev->driver = driv;1066dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr1067: dev->driver->driver_name;1068ret = driv->attach(dev, it);1069if (ret >= 0)1070ret = comedi_device_postconfig(dev);1071if (ret < 0) {1072comedi_device_detach(dev);1073module_put(driv->module);1074}1075/* On success, the driver module count has been incremented. */1076out:1077mutex_unlock(&comedi_drivers_list_lock);1078return ret;1079}10801081/**1082* comedi_auto_config() - Create a COMEDI device for a hardware device1083* @hardware_device: Hardware device.1084* @driver: COMEDI low-level driver for the hardware device.1085* @context: Driver context for the auto_attach handler.1086*1087* Allocates a new COMEDI device for the hardware device and calls the1088* low-level driver's 'auto_attach' handler to set-up the hardware and1089* allocate the COMEDI subdevices. Additional "post-configuration" setting1090* up is performed on successful return from the 'auto_attach' handler.1091* If the 'auto_attach' handler fails, the low-level driver's 'detach'1092* handler will be called as part of the clean-up.1093*1094* This is usually called from a wrapper function in a bus-specific COMEDI1095* module, which in turn is usually called from a bus device 'probe'1096* function in the low-level driver.1097*1098* Returns 0 on success, -EINVAL if the parameters are invalid or the1099* post-configuration determines the driver has set the COMEDI device up1100* incorrectly, -ENOMEM if failed to allocate memory, -EBUSY if run out of1101* COMEDI minor device numbers, or some negative error number returned by1102* the driver's 'auto_attach' handler.1103*/1104int comedi_auto_config(struct device *hardware_device,1105struct comedi_driver *driver, unsigned long context)1106{1107struct comedi_device *dev;1108int ret;11091110if (!hardware_device) {1111pr_warn("BUG! %s called with NULL hardware_device\n", __func__);1112return -EINVAL;1113}1114if (!driver) {1115dev_warn(hardware_device,1116"BUG! %s called with NULL comedi driver\n", __func__);1117return -EINVAL;1118}11191120if (!driver->auto_attach) {1121dev_warn(hardware_device,1122"BUG! comedi driver '%s' has no auto_attach handler\n",1123driver->driver_name);1124return -EINVAL;1125}11261127dev = comedi_alloc_board_minor(hardware_device);1128if (IS_ERR(dev)) {1129dev_warn(hardware_device,1130"driver '%s' could not create device.\n",1131driver->driver_name);1132return PTR_ERR(dev);1133}1134/* Note: comedi_alloc_board_minor() locked dev->mutex. */1135lockdep_assert_held(&dev->mutex);11361137dev->driver = driver;1138dev->board_name = dev->driver->driver_name;1139ret = driver->auto_attach(dev, context);1140if (ret >= 0)1141ret = comedi_device_postconfig(dev);11421143if (ret < 0) {1144dev_warn(hardware_device,1145"driver '%s' failed to auto-configure device.\n",1146driver->driver_name);1147mutex_unlock(&dev->mutex);1148comedi_release_hardware_device(hardware_device);1149} else {1150/*1151* class_dev should be set properly here1152* after a successful auto config1153*/1154dev_info(dev->class_dev,1155"driver '%s' has successfully auto-configured '%s'.\n",1156driver->driver_name, dev->board_name);1157mutex_unlock(&dev->mutex);1158}1159return ret;1160}1161EXPORT_SYMBOL_GPL(comedi_auto_config);11621163/**1164* comedi_auto_unconfig() - Unconfigure auto-allocated COMEDI device1165* @hardware_device: Hardware device previously passed to1166* comedi_auto_config().1167*1168* Cleans up and eventually destroys the COMEDI device allocated by1169* comedi_auto_config() for the same hardware device. As part of this1170* clean-up, the low-level COMEDI driver's 'detach' handler will be called.1171* (The COMEDI device itself will persist in an unattached state if it is1172* still open, until it is released, and any mmapped buffers will persist1173* until they are munmapped.)1174*1175* This is usually called from a wrapper module in a bus-specific COMEDI1176* module, which in turn is usually set as the bus device 'remove' function1177* in the low-level COMEDI driver.1178*/1179void comedi_auto_unconfig(struct device *hardware_device)1180{1181if (!hardware_device)1182return;1183comedi_release_hardware_device(hardware_device);1184}1185EXPORT_SYMBOL_GPL(comedi_auto_unconfig);11861187/**1188* comedi_driver_register() - Register a low-level COMEDI driver1189* @driver: Low-level COMEDI driver.1190*1191* The low-level COMEDI driver is added to the list of registered COMEDI1192* drivers. This is used by the handler for the "/proc/comedi" file and is1193* also used by the handler for the %COMEDI_DEVCONFIG ioctl to configure1194* "legacy" COMEDI devices (for those low-level drivers that support it).1195*1196* Returns 0.1197*/1198int comedi_driver_register(struct comedi_driver *driver)1199{1200mutex_lock(&comedi_drivers_list_lock);1201driver->next = comedi_drivers;1202comedi_drivers = driver;1203mutex_unlock(&comedi_drivers_list_lock);12041205return 0;1206}1207EXPORT_SYMBOL_GPL(comedi_driver_register);12081209/**1210* comedi_driver_unregister() - Unregister a low-level COMEDI driver1211* @driver: Low-level COMEDI driver.1212*1213* The low-level COMEDI driver is removed from the list of registered COMEDI1214* drivers. Detaches any COMEDI devices attached to the driver, which will1215* result in the low-level driver's 'detach' handler being called for those1216* devices before this function returns.1217*/1218void comedi_driver_unregister(struct comedi_driver *driver)1219{1220struct comedi_driver *prev;1221int i;12221223/* unlink the driver */1224mutex_lock(&comedi_drivers_list_lock);1225if (comedi_drivers == driver) {1226comedi_drivers = driver->next;1227} else {1228for (prev = comedi_drivers; prev->next; prev = prev->next) {1229if (prev->next == driver) {1230prev->next = driver->next;1231break;1232}1233}1234}1235mutex_unlock(&comedi_drivers_list_lock);12361237/* check for devices using this driver */1238for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {1239struct comedi_device *dev = comedi_dev_get_from_minor(i);12401241if (!dev)1242continue;12431244mutex_lock(&dev->mutex);1245if (dev->attached && dev->driver == driver) {1246if (dev->use_count)1247dev_warn(dev->class_dev,1248"BUG! detaching device with use_count=%d\n",1249dev->use_count);1250comedi_device_detach(dev);1251}1252mutex_unlock(&dev->mutex);1253comedi_dev_put(dev);1254}1255}1256EXPORT_SYMBOL_GPL(comedi_driver_unregister);125712581259