aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/pcl816.c
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2010-01-20 13:04:50 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-03 16:42:48 -0800
commit64a1f7bd56e0f26bd4dd621805facffde9fbb0a3 (patch)
tree33707258404d969651fa5d636f720c5434a9cb34 /drivers/staging/comedi/drivers/pcl816.c
parentc203b521e64e062d94f1ced1510206c0a55d5b55 (diff)
downloadkernel_samsung_smdk4412-64a1f7bd56e0f26bd4dd621805facffde9fbb0a3.zip
kernel_samsung_smdk4412-64a1f7bd56e0f26bd4dd621805facffde9fbb0a3.tar.gz
kernel_samsung_smdk4412-64a1f7bd56e0f26bd4dd621805facffde9fbb0a3.tar.bz2
Staging: comedi: pcl816: Check channel list in AI command test
Check the channel list is valid in step 5 of the AI command test. Split function check_and_setup_channel_list() in two. Also, remove unnecessary chanlist_len tests in step 3 of the AI command test as the comedi core has already checked it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/comedi/drivers/pcl816.c')
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 5c88ddc..9820759 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -214,9 +214,12 @@ struct pcl816_private {
/*
==============================================================================
*/
-static int check_and_setup_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist, int chanlen);
+static int check_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *chanlist, unsigned int chanlen);
+static void setup_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *chanlist, unsigned int seglen);
static int pcl816_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s);
static void start_pacer(struct comedi_device *dev, int mode,
@@ -566,14 +569,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->chanlist_len > this_board->n_aichan) {
- cmd->chanlist_len = this_board->n_aichan;
- err++;
- }
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
@@ -611,6 +606,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
return 4;
}
+ /* step 5: complain about special chanlist considerations */
+
+ if (cmd->chanlist) {
+ if (!check_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return 5; /* incorrect channels list */
+ }
+
return 0;
}
@@ -618,6 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int seglen;
if (cmd->start_src != TRIG_NOW)
return -EINVAL;
@@ -650,9 +654,10 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
start_pacer(dev, -1, 0, 0); /* stop pacer */
- if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
- cmd->chanlist_len))
+ seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
+ if (seglen < 1)
return -EINVAL;
+ setup_channel_list(dev, s, cmd->chanlist, seglen);
udelay(1);
devpriv->ai_n_chan = cmd->chanlist_len;
@@ -880,12 +885,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
/*
==============================================================================
Check if channel list from user is builded correctly
- If it's ok, then program scan/gain logic
+ If it's ok, then return non-zero length of repeated segment of channel list
*/
static int
-check_and_setup_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int *chanlist,
- int chanlen)
+check_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int *chanlist,
+ unsigned int chanlen)
{
unsigned int chansegment[16];
unsigned int i, nowmustbechan, seglen, segpos;
@@ -939,6 +944,20 @@ check_and_setup_channel_list(struct comedi_device *dev,
seglen = 1;
}
+ return seglen; /* we can serve this with MUX logic */
+}
+
+/*
+==============================================================================
+ Program scan/gain logic with channel list.
+*/
+static void
+setup_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int *chanlist,
+ unsigned int seglen)
+{
+ unsigned int i;
+
devpriv->ai_act_chanlist_len = seglen;
devpriv->ai_act_chanlist_pos = 0;
@@ -951,8 +970,6 @@ check_and_setup_channel_list(struct comedi_device *dev,
udelay(1);
outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */
-
- return 1; /* we can serve this with MUX logic */
}
#ifdef unused