From 64a1f7bd56e0f26bd4dd621805facffde9fbb0a3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 20 Jan 2010 13:04:50 +0000 Subject: [PATCH] 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 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 55 +++++++++++++++++++++------------ 1 file 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 -- 2.7.4