Commit 01fca378 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: drivers (core): remove forward declarations

Move a couple of the functions to avoid the need for the forward
declarations.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5b6cbd87
...@@ -45,14 +45,6 @@ ...@@ -45,14 +45,6 @@
#include "comedidev.h" #include "comedidev.h"
#include "comedi_internal.h" #include "comedi_internal.h"
static int postconfig(struct comedi_device *dev);
static int insn_rw_emulate_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data);
static void *comedi_recognize(struct comedi_driver *driv, const char *name);
static void comedi_report_boards(struct comedi_driver *driv);
static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s);
struct comedi_driver *comedi_drivers; struct comedi_driver *comedi_drivers;
int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
...@@ -131,121 +123,53 @@ void comedi_device_detach(struct comedi_device *dev) ...@@ -131,121 +123,53 @@ void comedi_device_detach(struct comedi_device *dev)
__comedi_device_detach(dev); __comedi_device_detach(dev);
} }
/* do a little post-config cleanup */ static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
/* called with module refcount incremented, decrements it */
static int comedi_device_postconfig(struct comedi_device *dev)
{
int ret = postconfig(dev);
module_put(dev->driver->module);
if (ret < 0) {
__comedi_device_detach(dev);
return ret;
}
if (!dev->board_name) {
dev_warn(dev->class_dev, "BUG: dev->board_name=NULL\n");
dev->board_name = "BUG";
}
smp_wmb();
dev->attached = 1;
return 0;
}
int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ {
struct comedi_driver *driv; return -EINVAL;
int ret;
if (dev->attached)
return -EBUSY;
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 == NULL) {
/* 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);
}
return -EIO;
}
if (driv->attach == NULL) {
/* 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);
return -ENOSYS;
}
/* initialize dev->driver here so
* comedi_error() can be called from attach */
dev->driver = driv;
ret = driv->attach(dev, it);
if (ret < 0) {
module_put(dev->driver->module);
__comedi_device_detach(dev);
return ret;
}
return comedi_device_postconfig(dev);
} }
int comedi_driver_register(struct comedi_driver *driver) int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{ {
driver->next = comedi_drivers; return -EINVAL;
comedi_drivers = driver;
return 0;
} }
EXPORT_SYMBOL(comedi_driver_register);
int comedi_driver_unregister(struct comedi_driver *driver) static int insn_rw_emulate_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{ {
struct comedi_driver *prev; struct comedi_insn new_insn;
int i; int ret;
static const unsigned channels_per_bitfield = 32;
/* check for devices using this driver */
for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
struct comedi_device *dev = comedi_dev_from_minor(i);
if (!dev) unsigned chan = CR_CHAN(insn->chanspec);
continue; const unsigned base_bitfield_channel =
(chan < channels_per_bitfield) ? 0 : chan;
unsigned int new_data[2];
memset(new_data, 0, sizeof(new_data));
memset(&new_insn, 0, sizeof(new_insn));
new_insn.insn = INSN_BITS;
new_insn.chanspec = base_bitfield_channel;
new_insn.n = 2;
new_insn.subdev = insn->subdev;
mutex_lock(&dev->mutex); if (insn->insn == INSN_WRITE) {
if (dev->attached && dev->driver == driver) { if (!(s->subdev_flags & SDF_WRITABLE))
if (dev->use_count) return -EINVAL;
dev_warn(dev->class_dev, new_data[0] = 1 << (chan - base_bitfield_channel); /* mask */
"BUG! detaching device with use_count=%d\n", new_data[1] = data[0] ? (1 << (chan - base_bitfield_channel))
dev->use_count); : 0; /* bits */
comedi_device_detach(dev);
}
mutex_unlock(&dev->mutex);
} }
if (comedi_drivers == driver) { ret = s->insn_bits(dev, s, &new_insn, new_data);
comedi_drivers = driver->next; if (ret < 0)
return 0; return ret;
}
for (prev = comedi_drivers; prev->next; prev = prev->next) { if (insn->insn == INSN_READ)
if (prev->next == driver) { data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
prev->next = driver->next;
return 0; return 1;
}
}
return -EINVAL;
} }
EXPORT_SYMBOL(comedi_driver_unregister);
static int postconfig(struct comedi_device *dev) static int postconfig(struct comedi_device *dev)
{ {
...@@ -326,6 +250,25 @@ static int postconfig(struct comedi_device *dev) ...@@ -326,6 +250,25 @@ static int postconfig(struct comedi_device *dev)
return 0; return 0;
} }
/* do a little post-config cleanup */
/* called with module refcount incremented, decrements it */
static int comedi_device_postconfig(struct comedi_device *dev)
{
int ret = postconfig(dev);
module_put(dev->driver->module);
if (ret < 0) {
__comedi_device_detach(dev);
return ret;
}
if (!dev->board_name) {
dev_warn(dev->class_dev, "BUG: dev->board_name=NULL\n");
dev->board_name = "BUG";
}
smp_wmb();
dev->attached = 1;
return 0;
}
/* /*
* Generic recognize function for drivers that register their supported * Generic recognize function for drivers that register their supported
* board names. * board names.
...@@ -384,53 +327,102 @@ static void comedi_report_boards(struct comedi_driver *driv) ...@@ -384,53 +327,102 @@ static void comedi_report_boards(struct comedi_driver *driv)
pr_info(" %s\n", driv->driver_name); pr_info(" %s\n", driv->driver_name);
} }
static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s) int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ {
return -EINVAL; struct comedi_driver *driv;
int ret;
if (dev->attached)
return -EBUSY;
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 == NULL) {
/* 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);
}
return -EIO;
}
if (driv->attach == NULL) {
/* 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);
return -ENOSYS;
}
/* initialize dev->driver here so
* comedi_error() can be called from attach */
dev->driver = driv;
ret = driv->attach(dev, it);
if (ret < 0) {
module_put(dev->driver->module);
__comedi_device_detach(dev);
return ret;
}
return comedi_device_postconfig(dev);
} }
int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, int comedi_driver_register(struct comedi_driver *driver)
struct comedi_insn *insn, unsigned int *data)
{ {
return -EINVAL; driver->next = comedi_drivers;
comedi_drivers = driver;
return 0;
} }
EXPORT_SYMBOL(comedi_driver_register);
static int insn_rw_emulate_bits(struct comedi_device *dev, int comedi_driver_unregister(struct comedi_driver *driver)
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{ {
struct comedi_insn new_insn; struct comedi_driver *prev;
int ret; int i;
static const unsigned channels_per_bitfield = 32;
unsigned chan = CR_CHAN(insn->chanspec); /* check for devices using this driver */
const unsigned base_bitfield_channel = for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
(chan < channels_per_bitfield) ? 0 : chan; struct comedi_device *dev = comedi_dev_from_minor(i);
unsigned int new_data[2];
memset(new_data, 0, sizeof(new_data));
memset(&new_insn, 0, sizeof(new_insn));
new_insn.insn = INSN_BITS;
new_insn.chanspec = base_bitfield_channel;
new_insn.n = 2;
new_insn.subdev = insn->subdev;
if (insn->insn == INSN_WRITE) { if (!dev)
if (!(s->subdev_flags & SDF_WRITABLE)) continue;
return -EINVAL;
new_data[0] = 1 << (chan - base_bitfield_channel); /* mask */
new_data[1] = data[0] ? (1 << (chan - base_bitfield_channel))
: 0; /* bits */
}
ret = s->insn_bits(dev, s, &new_insn, new_data); mutex_lock(&dev->mutex);
if (ret < 0) if (dev->attached && dev->driver == driver) {
return ret; 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);
}
if (insn->insn == INSN_READ) if (comedi_drivers == driver) {
data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1; comedi_drivers = driver->next;
return 0;
}
return 1; for (prev = comedi_drivers; prev->next; prev = prev->next) {
if (prev->next == driver) {
prev->next = driver->next;
return 0;
}
}
return -EINVAL;
} }
EXPORT_SYMBOL(comedi_driver_unregister);
int comedi_auto_config(struct device *hardware_device, int comedi_auto_config(struct device *hardware_device,
struct comedi_driver *driver, unsigned long context) struct comedi_driver *driver, unsigned long context)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment