Commit 64a1f7bd authored by Ian Abbott's avatar Ian Abbott Committed by Greg Kroah-Hartman

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: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c203b521
...@@ -214,9 +214,12 @@ struct pcl816_private { ...@@ -214,9 +214,12 @@ struct pcl816_private {
/* /*
============================================================================== ==============================================================================
*/ */
static int check_and_setup_channel_list(struct comedi_device *dev, static int check_channel_list(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
unsigned int *chanlist, int chanlen); 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, static int pcl816_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s); struct comedi_subdevice *s);
static void start_pacer(struct comedi_device *dev, int mode, static void start_pacer(struct comedi_device *dev, int mode,
...@@ -566,14 +569,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, ...@@ -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) { if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len; cmd->scan_end_arg = cmd->chanlist_len;
err++; err++;
...@@ -611,6 +606,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, ...@@ -611,6 +606,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
return 4; 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; return 0;
} }
...@@ -618,6 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -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; unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
struct comedi_cmd *cmd = &s->async->cmd; struct comedi_cmd *cmd = &s->async->cmd;
unsigned int seglen;
if (cmd->start_src != TRIG_NOW) if (cmd->start_src != TRIG_NOW)
return -EINVAL; return -EINVAL;
...@@ -650,9 +654,10 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -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 */ start_pacer(dev, -1, 0, 0); /* stop pacer */
if (!check_and_setup_channel_list(dev, s, cmd->chanlist, seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
cmd->chanlist_len)) if (seglen < 1)
return -EINVAL; return -EINVAL;
setup_channel_list(dev, s, cmd->chanlist, seglen);
udelay(1); udelay(1);
devpriv->ai_n_chan = cmd->chanlist_len; devpriv->ai_n_chan = cmd->chanlist_len;
...@@ -880,12 +885,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, ...@@ -880,12 +885,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
/* /*
============================================================================== ==============================================================================
Check if channel list from user is builded correctly 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 static int
check_and_setup_channel_list(struct comedi_device *dev, check_channel_list(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int *chanlist, struct comedi_subdevice *s, unsigned int *chanlist,
int chanlen) unsigned int chanlen)
{ {
unsigned int chansegment[16]; unsigned int chansegment[16];
unsigned int i, nowmustbechan, seglen, segpos; unsigned int i, nowmustbechan, seglen, segpos;
...@@ -939,6 +944,20 @@ check_and_setup_channel_list(struct comedi_device *dev, ...@@ -939,6 +944,20 @@ check_and_setup_channel_list(struct comedi_device *dev,
seglen = 1; 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_len = seglen;
devpriv->ai_act_chanlist_pos = 0; devpriv->ai_act_chanlist_pos = 0;
...@@ -951,8 +970,6 @@ check_and_setup_channel_list(struct comedi_device *dev, ...@@ -951,8 +970,6 @@ check_and_setup_channel_list(struct comedi_device *dev,
udelay(1); udelay(1);
outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */ 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 #ifdef unused
......
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