// 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);442443/**444* comedi_bytes_per_scan() - Get length of asynchronous command "scan" in bytes445* @s: COMEDI subdevice.446*447* Determines the overall scan length according to the subdevice type and the448* number of channels in the scan for the current command.449*450* For digital input, output or input/output subdevices, samples for451* multiple channels are assumed to be packed into one or more unsigned452* short or unsigned int values according to the subdevice's %SDF_LSAMPL453* flag. For other types of subdevice, samples are assumed to occupy a454* whole unsigned short or unsigned int according to the %SDF_LSAMPL flag.455*456* Returns the overall scan length in bytes.457*/458unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s)459{460struct comedi_cmd *cmd = &s->async->cmd;461462return comedi_bytes_per_scan_cmd(s, cmd);463}464EXPORT_SYMBOL_GPL(comedi_bytes_per_scan);465466static unsigned int __comedi_nscans_left(struct comedi_subdevice *s,467unsigned int nscans)468{469struct comedi_async *async = s->async;470struct comedi_cmd *cmd = &async->cmd;471472if (cmd->stop_src == TRIG_COUNT) {473unsigned int scans_left = 0;474475if (async->scans_done < cmd->stop_arg)476scans_left = cmd->stop_arg - async->scans_done;477478if (nscans > scans_left)479nscans = scans_left;480}481return nscans;482}483484/**485* comedi_nscans_left() - Return the number of scans left in the command486* @s: COMEDI subdevice.487* @nscans: The expected number of scans or 0 for all available scans.488*489* If @nscans is 0, it is set to the number of scans available in the490* async buffer.491*492* If the async command has a stop_src of %TRIG_COUNT, the @nscans will be493* checked against the number of scans remaining to complete the command.494*495* The return value will then be either the expected number of scans or the496* number of scans remaining to complete the command, whichever is fewer.497*/498unsigned 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}508EXPORT_SYMBOL_GPL(comedi_nscans_left);509510/**511* comedi_nsamples_left() - Return the number of samples left in the command512* @s: COMEDI subdevice.513* @nsamples: The expected number of samples.514*515* Returns the number of samples remaining to complete the command, or the516* specified expected number of samples (@nsamples), whichever is fewer.517*/518unsigned int comedi_nsamples_left(struct comedi_subdevice *s,519unsigned int nsamples)520{521struct comedi_async *async = s->async;522struct comedi_cmd *cmd = &async->cmd;523unsigned long long scans_left;524unsigned long long samples_left;525526if (cmd->stop_src != TRIG_COUNT)527return nsamples;528529scans_left = __comedi_nscans_left(s, cmd->stop_arg);530if (!scans_left)531return 0;532533samples_left = scans_left * cmd->scan_end_arg -534comedi_bytes_to_samples(s, async->scan_progress);535536if (samples_left < nsamples)537return samples_left;538return nsamples;539}540EXPORT_SYMBOL_GPL(comedi_nsamples_left);541542/**543* comedi_inc_scan_progress() - Update scan progress in asynchronous command544* @s: COMEDI subdevice.545* @num_bytes: Amount of data in bytes to increment scan progress.546*547* Increments the scan progress by the number of bytes specified by @num_bytes.548* If the scan progress reaches or exceeds the scan length in bytes, reduce549* it modulo the scan length in bytes and set the "end of scan" asynchronous550* event flag (%COMEDI_CB_EOS) to be processed later.551*/552void comedi_inc_scan_progress(struct comedi_subdevice *s,553unsigned int num_bytes)554{555struct comedi_async *async = s->async;556struct comedi_cmd *cmd = &async->cmd;557unsigned int scan_length = comedi_bytes_per_scan(s);558559/* track the 'cur_chan' for non-SDF_PACKED subdevices */560if (!(s->subdev_flags & SDF_PACKED)) {561async->cur_chan += comedi_bytes_to_samples(s, num_bytes);562async->cur_chan %= cmd->chanlist_len;563}564565async->scan_progress += num_bytes;566if (async->scan_progress >= scan_length) {567unsigned int nscans = async->scan_progress / scan_length;568569if (async->scans_done < (UINT_MAX - nscans))570async->scans_done += nscans;571else572async->scans_done = UINT_MAX;573574async->scan_progress %= scan_length;575async->events |= COMEDI_CB_EOS;576}577}578EXPORT_SYMBOL_GPL(comedi_inc_scan_progress);579580/**581* comedi_handle_events() - Handle events and possibly stop acquisition582* @dev: COMEDI device.583* @s: COMEDI subdevice.584*585* Handles outstanding asynchronous acquisition event flags associated586* with the subdevice. Call the subdevice's @s->cancel() handler if the587* "end of acquisition", "error" or "overflow" event flags are set in order588* to stop the acquisition at the driver level.589*590* Calls comedi_event() to further process the event flags, which may mark591* the asynchronous command as no longer running, possibly terminated with592* an error, and may wake up tasks.593*594* Return a bit-mask of the handled events.595*/596unsigned int comedi_handle_events(struct comedi_device *dev,597struct comedi_subdevice *s)598{599unsigned int events = s->async->events;600601if (events == 0)602return events;603604if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel)605s->cancel(dev, s);606607comedi_event(dev, s);608609return events;610}611EXPORT_SYMBOL_GPL(comedi_handle_events);612613static int insn_rw_emulate_bits(struct comedi_device *dev,614struct comedi_subdevice *s,615struct comedi_insn *insn,616unsigned int *data)617{618struct comedi_insn _insn;619unsigned int chan = CR_CHAN(insn->chanspec);620unsigned int base_chan = (chan < 32) ? 0 : chan;621unsigned int _data[2];622unsigned int i;623int ret;624625memset(_data, 0, sizeof(_data));626memset(&_insn, 0, sizeof(_insn));627_insn.insn = INSN_BITS;628_insn.chanspec = base_chan;629_insn.n = 2;630_insn.subdev = insn->subdev;631632if (insn->insn == INSN_WRITE) {633if (!(s->subdev_flags & SDF_WRITABLE))634return -EINVAL;635_data[0] = 1U << (chan - base_chan); /* mask */636}637for (i = 0; i < insn->n; i++) {638if (insn->insn == INSN_WRITE)639_data[1] = data[i] ? _data[0] : 0; /* bits */640641ret = s->insn_bits(dev, s, &_insn, _data);642if (ret < 0)643return ret;644645if (insn->insn == INSN_READ)646data[i] = (_data[1] >> (chan - base_chan)) & 1;647}648649return insn->n;650}651652static int __comedi_device_postconfig_async(struct comedi_device *dev,653struct comedi_subdevice *s)654{655struct comedi_async *async;656unsigned int buf_size;657int ret;658659lockdep_assert_held(&dev->mutex);660if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) {661dev_warn(dev->class_dev,662"async subdevices must support SDF_CMD_READ or SDF_CMD_WRITE\n");663return -EINVAL;664}665if (!s->do_cmdtest) {666dev_warn(dev->class_dev,667"async subdevices must have a do_cmdtest() function\n");668return -EINVAL;669}670if (!s->cancel)671dev_warn(dev->class_dev,672"async subdevices should have a cancel() function\n");673674async = kzalloc(sizeof(*async), GFP_KERNEL);675if (!async)676return -ENOMEM;677678init_waitqueue_head(&async->wait_head);679s->async = async;680681async->max_bufsize = comedi_default_buf_maxsize_kb * 1024;682buf_size = comedi_default_buf_size_kb * 1024;683if (buf_size > async->max_bufsize)684buf_size = async->max_bufsize;685686if (comedi_buf_alloc(dev, s, buf_size) < 0) {687dev_warn(dev->class_dev, "Buffer allocation failed\n");688return -ENOMEM;689}690if (s->buf_change) {691ret = s->buf_change(dev, s);692if (ret < 0)693return ret;694}695696comedi_alloc_subdevice_minor(s);697698return 0;699}700701static int __comedi_device_postconfig(struct comedi_device *dev)702{703struct comedi_subdevice *s;704int ret;705int i;706707lockdep_assert_held(&dev->mutex);708if (!dev->insn_device_config)709dev->insn_device_config = insn_device_inval;710711if (!dev->get_valid_routes)712dev->get_valid_routes = get_zero_valid_routes;713714for (i = 0; i < dev->n_subdevices; i++) {715s = &dev->subdevices[i];716717if (s->type == COMEDI_SUBD_UNUSED)718continue;719720if (s->type == COMEDI_SUBD_DO) {721if (s->n_chan < 32)722s->io_bits = (1U << s->n_chan) - 1;723else724s->io_bits = 0xffffffff;725}726727if (s->len_chanlist == 0)728s->len_chanlist = 1;729730if (s->do_cmd) {731ret = __comedi_device_postconfig_async(dev, s);732if (ret)733return ret;734}735736if (!s->range_table && !s->range_table_list)737s->range_table = &range_unknown;738739if (!s->insn_read && s->insn_bits)740s->insn_read = insn_rw_emulate_bits;741if (!s->insn_write && s->insn_bits)742s->insn_write = insn_rw_emulate_bits;743744if (!s->insn_read)745s->insn_read = insn_inval;746if (!s->insn_write)747s->insn_write = insn_inval;748if (!s->insn_bits)749s->insn_bits = insn_inval;750if (!s->insn_config)751s->insn_config = insn_inval;752753if (!s->poll)754s->poll = poll_invalid;755}756757return 0;758}759760/* do a little post-config cleanup */761static int comedi_device_postconfig(struct comedi_device *dev)762{763int ret;764765lockdep_assert_held(&dev->mutex);766ret = __comedi_device_postconfig(dev);767if (ret < 0)768return ret;769down_write(&dev->attach_lock);770dev->attached = true;771up_write(&dev->attach_lock);772return 0;773}774775/*776* Generic recognize function for drivers that register their supported777* board names.778*779* 'driv->board_name' points to a 'const char *' member within the780* zeroth element of an array of some private board information781* structure, say 'struct foo_board' containing a member 'const char782* *board_name' that is initialized to point to a board name string that783* is one of the candidates matched against this function's 'name'784* parameter.785*786* 'driv->offset' is the size of the private board information787* structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is788* the length of the array of private board information structures.789*790* If one of the board names in the array of private board information791* structures matches the name supplied to this function, the function792* returns a pointer to the pointer to the board name, otherwise it793* returns NULL. The return value ends up in the 'board_ptr' member of794* a 'struct comedi_device' that the low-level comedi driver's795* 'attach()' hook can convert to a point to a particular element of its796* array of private board information structures by subtracting the797* offset of the member that points to the board name. (No subtraction798* is required if the board name pointer is the first member of the799* private board information structure, which is generally the case.)800*/801static void *comedi_recognize(struct comedi_driver *driv, const char *name)802{803char **name_ptr = (char **)driv->board_name;804int i;805806for (i = 0; i < driv->num_names; i++) {807if (strcmp(*name_ptr, name) == 0)808return name_ptr;809name_ptr = (void *)name_ptr + driv->offset;810}811812return NULL;813}814815static void comedi_report_boards(struct comedi_driver *driv)816{817unsigned int i;818const char *const *name_ptr;819820pr_info("comedi: valid board names for %s driver are:\n",821driv->driver_name);822823name_ptr = driv->board_name;824for (i = 0; i < driv->num_names; i++) {825pr_info(" %s\n", *name_ptr);826name_ptr = (const char **)((char *)name_ptr + driv->offset);827}828829if (driv->num_names == 0)830pr_info(" %s\n", driv->driver_name);831}832833/**834* comedi_load_firmware() - Request and load firmware for a device835* @dev: COMEDI device.836* @device: Hardware device.837* @name: The name of the firmware image.838* @cb: Callback to the upload the firmware image.839* @context: Private context from the driver.840*841* Sends a firmware request for the hardware device and waits for it. Calls842* the callback function to upload the firmware to the device, them releases843* the firmware.844*845* Returns 0 on success, -EINVAL if @cb is NULL, or a negative error number846* from the firmware request or the callback function.847*/848int comedi_load_firmware(struct comedi_device *dev,849struct device *device,850const char *name,851int (*cb)(struct comedi_device *dev,852const u8 *data, size_t size,853unsigned long context),854unsigned long context)855{856const struct firmware *fw;857int ret;858859if (!cb)860return -EINVAL;861862ret = request_firmware(&fw, name, device);863if (ret == 0) {864ret = cb(dev, fw->data, fw->size, context);865release_firmware(fw);866}867868return min(ret, 0);869}870EXPORT_SYMBOL_GPL(comedi_load_firmware);871872/**873* __comedi_request_region() - Request an I/O region for a legacy driver874* @dev: COMEDI device.875* @start: Base address of the I/O region.876* @len: Length of the I/O region.877*878* Requests the specified I/O port region which must start at a non-zero879* address.880*881* Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request882* fails.883*/884int __comedi_request_region(struct comedi_device *dev,885unsigned long start, unsigned long len)886{887if (!start) {888dev_warn(dev->class_dev,889"%s: a I/O base address must be specified\n",890dev->board_name);891return -EINVAL;892}893894if (!request_region(start, len, dev->board_name)) {895dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",896dev->board_name, start, len);897return -EIO;898}899900return 0;901}902EXPORT_SYMBOL_GPL(__comedi_request_region);903904/**905* comedi_request_region() - Request an I/O region for a legacy driver906* @dev: COMEDI device.907* @start: Base address of the I/O region.908* @len: Length of the I/O region.909*910* Requests the specified I/O port region which must start at a non-zero911* address.912*913* On success, @dev->iobase is set to the base address of the region and914* @dev->iolen is set to its length.915*916* Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request917* fails.918*/919int comedi_request_region(struct comedi_device *dev,920unsigned long start, unsigned long len)921{922int ret;923924ret = __comedi_request_region(dev, start, len);925if (ret == 0) {926dev->iobase = start;927dev->iolen = len;928}929930return ret;931}932EXPORT_SYMBOL_GPL(comedi_request_region);933934/**935* comedi_legacy_detach() - A generic (*detach) function for legacy drivers936* @dev: COMEDI device.937*938* This is a simple, generic 'detach' handler for legacy COMEDI devices that939* just use a single I/O port region and possibly an IRQ and that don't need940* any special clean-up for their private device or subdevice storage. It941* can also be called by a driver-specific 'detach' handler.942*943* If @dev->irq is non-zero, the IRQ will be freed. If @dev->iobase and944* @dev->iolen are both non-zero, the I/O port region will be released.945*/946void comedi_legacy_detach(struct comedi_device *dev)947{948if (dev->irq) {949free_irq(dev->irq, dev);950dev->irq = 0;951}952if (dev->iobase && dev->iolen) {953release_region(dev->iobase, dev->iolen);954dev->iobase = 0;955dev->iolen = 0;956}957}958EXPORT_SYMBOL_GPL(comedi_legacy_detach);959960int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)961{962struct comedi_driver *driv;963int ret;964965lockdep_assert_held(&dev->mutex);966if (dev->attached)967return -EBUSY;968969mutex_lock(&comedi_drivers_list_lock);970for (driv = comedi_drivers; driv; driv = driv->next) {971if (!try_module_get(driv->module))972continue;973if (driv->num_names) {974dev->board_ptr = comedi_recognize(driv, it->board_name);975if (dev->board_ptr)976break;977} else if (strcmp(driv->driver_name, it->board_name) == 0) {978break;979}980module_put(driv->module);981}982if (!driv) {983/* recognize has failed if we get here */984/* report valid board names before returning error */985for (driv = comedi_drivers; driv; driv = driv->next) {986if (!try_module_get(driv->module))987continue;988comedi_report_boards(driv);989module_put(driv->module);990}991ret = -EIO;992goto out;993}994if (!driv->attach) {995/* driver does not support manual configuration */996dev_warn(dev->class_dev,997"driver '%s' does not support attach using comedi_config\n",998driv->driver_name);999module_put(driv->module);1000ret = -EIO;1001goto out;1002}1003dev->driver = driv;1004dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr1005: dev->driver->driver_name;1006ret = driv->attach(dev, it);1007if (ret >= 0)1008ret = comedi_device_postconfig(dev);1009if (ret < 0) {1010comedi_device_detach(dev);1011module_put(driv->module);1012}1013/* On success, the driver module count has been incremented. */1014out:1015mutex_unlock(&comedi_drivers_list_lock);1016return ret;1017}10181019/**1020* comedi_auto_config() - Create a COMEDI device for a hardware device1021* @hardware_device: Hardware device.1022* @driver: COMEDI low-level driver for the hardware device.1023* @context: Driver context for the auto_attach handler.1024*1025* Allocates a new COMEDI device for the hardware device and calls the1026* low-level driver's 'auto_attach' handler to set-up the hardware and1027* allocate the COMEDI subdevices. Additional "post-configuration" setting1028* up is performed on successful return from the 'auto_attach' handler.1029* If the 'auto_attach' handler fails, the low-level driver's 'detach'1030* handler will be called as part of the clean-up.1031*1032* This is usually called from a wrapper function in a bus-specific COMEDI1033* module, which in turn is usually called from a bus device 'probe'1034* function in the low-level driver.1035*1036* Returns 0 on success, -EINVAL if the parameters are invalid or the1037* post-configuration determines the driver has set the COMEDI device up1038* incorrectly, -ENOMEM if failed to allocate memory, -EBUSY if run out of1039* COMEDI minor device numbers, or some negative error number returned by1040* the driver's 'auto_attach' handler.1041*/1042int comedi_auto_config(struct device *hardware_device,1043struct comedi_driver *driver, unsigned long context)1044{1045struct comedi_device *dev;1046int ret;10471048if (!hardware_device) {1049pr_warn("BUG! %s called with NULL hardware_device\n", __func__);1050return -EINVAL;1051}1052if (!driver) {1053dev_warn(hardware_device,1054"BUG! %s called with NULL comedi driver\n", __func__);1055return -EINVAL;1056}10571058if (!driver->auto_attach) {1059dev_warn(hardware_device,1060"BUG! comedi driver '%s' has no auto_attach handler\n",1061driver->driver_name);1062return -EINVAL;1063}10641065dev = comedi_alloc_board_minor(hardware_device);1066if (IS_ERR(dev)) {1067dev_warn(hardware_device,1068"driver '%s' could not create device.\n",1069driver->driver_name);1070return PTR_ERR(dev);1071}1072/* Note: comedi_alloc_board_minor() locked dev->mutex. */1073lockdep_assert_held(&dev->mutex);10741075dev->driver = driver;1076dev->board_name = dev->driver->driver_name;1077ret = driver->auto_attach(dev, context);1078if (ret >= 0)1079ret = comedi_device_postconfig(dev);10801081if (ret < 0) {1082dev_warn(hardware_device,1083"driver '%s' failed to auto-configure device.\n",1084driver->driver_name);1085mutex_unlock(&dev->mutex);1086comedi_release_hardware_device(hardware_device);1087} else {1088/*1089* class_dev should be set properly here1090* after a successful auto config1091*/1092dev_info(dev->class_dev,1093"driver '%s' has successfully auto-configured '%s'.\n",1094driver->driver_name, dev->board_name);1095mutex_unlock(&dev->mutex);1096}1097return ret;1098}1099EXPORT_SYMBOL_GPL(comedi_auto_config);11001101/**1102* comedi_auto_unconfig() - Unconfigure auto-allocated COMEDI device1103* @hardware_device: Hardware device previously passed to1104* comedi_auto_config().1105*1106* Cleans up and eventually destroys the COMEDI device allocated by1107* comedi_auto_config() for the same hardware device. As part of this1108* clean-up, the low-level COMEDI driver's 'detach' handler will be called.1109* (The COMEDI device itself will persist in an unattached state if it is1110* still open, until it is released, and any mmapped buffers will persist1111* until they are munmapped.)1112*1113* This is usually called from a wrapper module in a bus-specific COMEDI1114* module, which in turn is usually set as the bus device 'remove' function1115* in the low-level COMEDI driver.1116*/1117void comedi_auto_unconfig(struct device *hardware_device)1118{1119if (!hardware_device)1120return;1121comedi_release_hardware_device(hardware_device);1122}1123EXPORT_SYMBOL_GPL(comedi_auto_unconfig);11241125/**1126* comedi_driver_register() - Register a low-level COMEDI driver1127* @driver: Low-level COMEDI driver.1128*1129* The low-level COMEDI driver is added to the list of registered COMEDI1130* drivers. This is used by the handler for the "/proc/comedi" file and is1131* also used by the handler for the %COMEDI_DEVCONFIG ioctl to configure1132* "legacy" COMEDI devices (for those low-level drivers that support it).1133*1134* Returns 0.1135*/1136int comedi_driver_register(struct comedi_driver *driver)1137{1138mutex_lock(&comedi_drivers_list_lock);1139driver->next = comedi_drivers;1140comedi_drivers = driver;1141mutex_unlock(&comedi_drivers_list_lock);11421143return 0;1144}1145EXPORT_SYMBOL_GPL(comedi_driver_register);11461147/**1148* comedi_driver_unregister() - Unregister a low-level COMEDI driver1149* @driver: Low-level COMEDI driver.1150*1151* The low-level COMEDI driver is removed from the list of registered COMEDI1152* drivers. Detaches any COMEDI devices attached to the driver, which will1153* result in the low-level driver's 'detach' handler being called for those1154* devices before this function returns.1155*/1156void comedi_driver_unregister(struct comedi_driver *driver)1157{1158struct comedi_driver *prev;1159int i;11601161/* unlink the driver */1162mutex_lock(&comedi_drivers_list_lock);1163if (comedi_drivers == driver) {1164comedi_drivers = driver->next;1165} else {1166for (prev = comedi_drivers; prev->next; prev = prev->next) {1167if (prev->next == driver) {1168prev->next = driver->next;1169break;1170}1171}1172}1173mutex_unlock(&comedi_drivers_list_lock);11741175/* check for devices using this driver */1176for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {1177struct comedi_device *dev = comedi_dev_get_from_minor(i);11781179if (!dev)1180continue;11811182mutex_lock(&dev->mutex);1183if (dev->attached && dev->driver == driver) {1184if (dev->use_count)1185dev_warn(dev->class_dev,1186"BUG! detaching device with use_count=%d\n",1187dev->use_count);1188comedi_device_detach(dev);1189}1190mutex_unlock(&dev->mutex);1191comedi_dev_put(dev);1192}1193}1194EXPORT_SYMBOL_GPL(comedi_driver_unregister);119511961197