[PATCH RFC] staging: comedi: fix user/kernel space access of cmd->chanlist

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The 'chanlist' in the comedi_cmd struct is an unsigned int __user
pointer.

The do_cmd_ioctl() and do_cmdtest_ioctl() functions in comedi_fops
do a copy_from_user() to move the data from user space to kernel
space before passing the comedi_cmd to the comedi drivers.

Unfortunately, the drivers then think 'chanlist' is still a
__user pointer since thats how the struct is defined.

Make the 'chanlist' a union of both a __user and kernel pointer.
The do_cmd_*_ioctl() functions are the only ones that use the
__user pointer. All the drivers then use the kernel pointer to
access the chanlist.

This fixes a bunch of sparse warnings about:

  warning: incorrect type in argument n (different address spaces)

and

  warning: incorrect type in assignment (different address spaces)

Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---

Unfortunately, I don't see any way to split this patch up. The
change to struct comedi_cmd breaks the build unless all the
files are patched at once.

If this approach looks right, I would like Ian's sign off before it's
merged. Hopefully he is able to actually test something...

 drivers/staging/comedi/comedi.h                    |  5 +-
 drivers/staging/comedi/comedi_fops.c               | 45 +++++++-------
 .../comedi/drivers/addi-data/hwdrv_apci3120.c      |  3 +-
 drivers/staging/comedi/drivers/adl_pci9111.c       | 18 +++---
 drivers/staging/comedi/drivers/adl_pci9118.c       |  8 ++-
 drivers/staging/comedi/drivers/adv_pci1710.c       |  8 ++-
 drivers/staging/comedi/drivers/amplc_dio200.c      |  8 ++-
 drivers/staging/comedi/drivers/amplc_pci224.c      | 22 ++++---
 drivers/staging/comedi/drivers/amplc_pci230.c      | 60 +++++++++---------
 drivers/staging/comedi/drivers/cb_pcidas.c         | 37 ++++++-----
 drivers/staging/comedi/drivers/cb_pcidas64.c       | 72 +++++++++++-----------
 drivers/staging/comedi/drivers/comedi_test.c       | 19 +++---
 drivers/staging/comedi/drivers/das16.c             | 18 +++---
 drivers/staging/comedi/drivers/das16m1.c           | 11 ++--
 drivers/staging/comedi/drivers/das1800.c           | 20 +++---
 drivers/staging/comedi/drivers/das800.c            | 16 ++---
 drivers/staging/comedi/drivers/dmm32at.c           | 18 +++---
 drivers/staging/comedi/drivers/dt2814.c            |  3 +-
 drivers/staging/comedi/drivers/dt282x.c            |  3 +-
 drivers/staging/comedi/drivers/dt3000.c            |  7 ++-
 drivers/staging/comedi/drivers/gsc_hpdi.c          |  5 +-
 drivers/staging/comedi/drivers/me4000.c            | 22 ++++---
 drivers/staging/comedi/drivers/ni_at_a2150.c       | 21 ++++---
 drivers/staging/comedi/drivers/ni_atmio16d.c       |  5 +-
 drivers/staging/comedi/drivers/ni_labpc.c          | 38 +++++++-----
 drivers/staging/comedi/drivers/ni_mio_common.c     | 22 ++++---
 drivers/staging/comedi/drivers/pcl711.c            |  3 +-
 drivers/staging/comedi/drivers/pcl812.c            |  3 +-
 drivers/staging/comedi/drivers/pcl816.c            | 10 +--
 drivers/staging/comedi/drivers/pcl818.c            |  8 ++-
 drivers/staging/comedi/drivers/pcmmio.c            | 48 ++++++++-------
 drivers/staging/comedi/drivers/pcmuio.c            | 48 ++++++++-------
 drivers/staging/comedi/drivers/quatech_daqp_cs.c   |  3 +-
 drivers/staging/comedi/drivers/rtd520.c            |  3 +-
 drivers/staging/comedi/drivers/s626.c              |  8 +--
 drivers/staging/comedi/drivers/usbdux.c            | 59 ++++++++----------
 drivers/staging/comedi/drivers/usbduxfast.c        | 23 +++----
 drivers/staging/comedi/drivers/usbduxsigma.c       | 10 +--
 38 files changed, 397 insertions(+), 343 deletions(-)

diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 8ea55ae..f986370 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -365,7 +365,10 @@
 		unsigned int stop_src;
 		unsigned int stop_arg;
 
-		unsigned int __user *chanlist;	/* channel/range list */
+		union {
+			unsigned int __user *user_data;
+			unsigned int *kernel_data;
+		} chanlist;		/* channel/range list */
 		unsigned int chanlist_len;
 
 		short __user *data; /* data list, size depends on subd flags */
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 00d8d1f..4d98a21 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1136,15 +1136,17 @@ static int do_cmd_ioctl(struct comedi_device *dev,
 	struct comedi_cmd user_cmd;
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
+	unsigned int __user *user_chanlist;
+	unsigned int *chanlist;
+	unsigned int chanlist_size;
 	int ret = 0;
-	unsigned int __user *chanlist_saver = NULL;
 
 	if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) {
 		DPRINTK("bad cmd address\n");
 		return -EFAULT;
 	}
 	/* save user's chanlist pointer so it can be restored later */
-	chanlist_saver = user_cmd.chanlist;
+	user_chanlist = user_cmd.chanlist.user_data;
 
 	if (user_cmd.subdev >= dev->n_subdevices) {
 		DPRINTK("%d no such subdevice\n", user_cmd.subdev);
@@ -1194,29 +1196,28 @@ static int do_cmd_ioctl(struct comedi_device *dev,
 		goto cleanup;
 	}
 
-	kfree(async->cmd.chanlist);
+	kfree(async->cmd.chanlist.kernel_data);
 	async->cmd = user_cmd;
 	async->cmd.data = NULL;
+	chanlist_size = async->cmd.chanlist_len * sizeof(unsigned int);
 	/* load channel/gain list */
-	async->cmd.chanlist =
-	    kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL);
-	if (!async->cmd.chanlist) {
+	chanlist = kzalloc(chanlist_size, GFP_KERNEL);
+	if (!chanlist) {
 		DPRINTK("allocation failed\n");
 		ret = -ENOMEM;
 		goto cleanup;
 	}
+	async->cmd.chanlist.kernel_data = chanlist;
 
-	if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist,
-			   async->cmd.chanlist_len * sizeof(int))) {
+	if (copy_from_user(chanlist, user_chanlist, chanlist_size)) {
 		DPRINTK("fault reading chanlist\n");
 		ret = -EFAULT;
 		goto cleanup;
 	}
 
 	/* make sure each element in channel/gain list is valid */
-	ret = comedi_check_chanlist(s,
-				    async->cmd.chanlist_len,
-				    async->cmd.chanlist);
+	ret = comedi_check_chanlist(s, async->cmd.chanlist_len,
+				    chanlist);
 	if (ret < 0) {
 		DPRINTK("bad chanlist\n");
 		goto cleanup;
@@ -1228,7 +1229,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
 		DPRINTK("test returned %d\n", ret);
 		user_cmd = async->cmd;
 		/* restore chanlist pointer before copying back */
-		user_cmd.chanlist = chanlist_saver;
+		user_cmd.chanlist.user_data = user_chanlist;
 		user_cmd.data = NULL;
 		if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) {
 			DPRINTK("fault writing cmd\n");
@@ -1285,16 +1286,17 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
 {
 	struct comedi_cmd user_cmd;
 	struct comedi_subdevice *s;
-	int ret = 0;
+	unsigned int __user *user_chanlist;
 	unsigned int *chanlist = NULL;
-	unsigned int __user *chanlist_saver = NULL;
+	unsigned int chanlist_size;
+	int ret = 0;
 
 	if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
 		DPRINTK("bad cmd address\n");
 		return -EFAULT;
 	}
 	/* save user's chanlist pointer so it can be restored later */
-	chanlist_saver = user_cmd.chanlist;
+	user_chanlist = user_cmd.chanlist.user_data;
 
 	if (user_cmd.subdev >= dev->n_subdevices) {
 		DPRINTK("%d no such subdevice\n", user_cmd.subdev);
@@ -1322,17 +1324,16 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
 	}
 
 	/* load channel/gain list */
-	if (user_cmd.chanlist) {
-		chanlist =
-		    kmalloc(user_cmd.chanlist_len * sizeof(int), GFP_KERNEL);
+	if (user_cmd.chanlist.user_data) {
+		chanlist_size = user_cmd.chanlist_len * sizeof(unsigned int);
+		chanlist = kzalloc(chanlist_size, GFP_KERNEL);
 		if (!chanlist) {
 			DPRINTK("allocation failed\n");
 			ret = -ENOMEM;
 			goto cleanup;
 		}
 
-		if (copy_from_user(chanlist, user_cmd.chanlist,
-				   user_cmd.chanlist_len * sizeof(int))) {
+		if (copy_from_user(chanlist, user_chanlist, chanlist_size)) {
 			DPRINTK("fault reading chanlist\n");
 			ret = -EFAULT;
 			goto cleanup;
@@ -1345,13 +1346,13 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
 			goto cleanup;
 		}
 
-		user_cmd.chanlist = chanlist;
+		user_cmd.chanlist.kernel_data = chanlist;
 	}
 
 	ret = s->do_cmdtest(dev, s, &user_cmd);
 
 	/* restore chanlist pointer before copying back */
-	user_cmd.chanlist = chanlist_saver;
+	user_cmd.chanlist.user_data = user_chanlist;
 
 	if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
 		DPRINTK("bad cmd address\n");
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index d61fce0..867376b 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -636,12 +636,13 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
 int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 
 	/* loading private structure with cmd structure inputs */
 	devpriv->ui_AiFlags = cmd->flags;
 	devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
 	devpriv->ui_AiScanLength = cmd->scan_end_arg;
-	devpriv->pui_AiChannelList = cmd->chanlist;
+	devpriv->pui_AiChannelList = chanlist;
 
 	/* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */
 	devpriv->AiData = s->async->prealloc_buf;
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 91efaa4..9fe68d1 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -327,6 +327,7 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
 				  struct comedi_cmd *cmd)
 {
 	struct pci9111_private_data *dev_private = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int tmp;
 	int error = 0;
 	int range, reference;
@@ -460,25 +461,25 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
 
 	/*  Step 5 : check channel list */
 
-	if (cmd->chanlist) {
+	if (chanlist) {
 
-		range = CR_RANGE(cmd->chanlist[0]);
-		reference = CR_AREF(cmd->chanlist[0]);
+		range = CR_RANGE(chanlist[0]);
+		reference = CR_AREF(chanlist[0]);
 
 		if (cmd->chanlist_len > 1) {
 			for (i = 0; i < cmd->chanlist_len; i++) {
-				if (CR_CHAN(cmd->chanlist[i]) != i) {
+				if (CR_CHAN(chanlist[i]) != i) {
 					comedi_error(dev,
 						     "entries in chanlist must be consecutive "
 						     "channels,counting upwards from 0\n");
 					error++;
 				}
-				if (CR_RANGE(cmd->chanlist[i]) != range) {
+				if (CR_RANGE(chanlist[i]) != range) {
 					comedi_error(dev,
 						     "entries in chanlist must all have the same gain\n");
 					error++;
 				}
-				if (CR_AREF(cmd->chanlist[i]) != reference) {
+				if (CR_AREF(chanlist[i]) != reference) {
 					comedi_error(dev,
 						     "entries in chanlist must all have the same reference\n");
 					error++;
@@ -499,6 +500,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
 {
 	struct pci9111_private_data *dev_private = dev->private;
 	struct comedi_cmd *async_cmd = &s->async->cmd;
+	unsigned int *chanlist = async_cmd->chanlist.kernel_data;
 
 	if (!dev->irq) {
 		comedi_error(dev,
@@ -514,7 +516,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
 			dev->iobase + PCI9111_AI_CHANNEL_REG);
 		pci9111_autoscan_set(dev, true);
 	} else {
-		outb(CR_CHAN(async_cmd->chanlist[0]),
+		outb(CR_CHAN(chanlist[0]),
 			dev->iobase + PCI9111_AI_CHANNEL_REG);
 		pci9111_autoscan_set(dev, false);
 	}
@@ -522,7 +524,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
 	/*  Set gain */
 	/*  This is the same gain on every channel */
 
-	outb(CR_RANGE(async_cmd->chanlist[0]) & PCI9111_AI_RANGE_MASK,
+	outb(CR_RANGE(chanlist[0]) & PCI9111_AI_RANGE_MASK,
 		dev->iobase + PCI9111_AI_RANGE_STAT_REG);
 
 	/* Set counter */
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index f7b254d..ec35673 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -1097,6 +1097,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 {
 	const struct boardtype *this_board = comedi_board(dev);
 	struct pci9118_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	unsigned int flags;
 	int tmp;
@@ -1325,9 +1326,9 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 	if (err)
 		return 4;
 
-	if (cmd->chanlist)
+	if (chanlist)
 		if (!check_channel_list(dev, s, cmd->chanlist_len,
-					cmd->chanlist, 0, 0))
+					chanlist, 0, 0))
 			return 5;	/* incorrect channels list */
 
 	return 0;
@@ -1614,6 +1615,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	const struct boardtype *this_board = comedi_board(dev);
 	struct pci9118_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int addchans = 0;
 	int ret = 0;
 
@@ -1621,7 +1623,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->ai_flags = cmd->flags;
 	devpriv->ai_n_chan = cmd->chanlist_len;
 	devpriv->ai_n_scanlen = cmd->scan_end_arg;
-	devpriv->ai_chanlist = cmd->chanlist;
+	devpriv->ai_chanlist = chanlist;
 	devpriv->ai_data = s->async->prealloc_buf;
 	devpriv->ai_data_len = s->async->prealloc_bufsz;
 	devpriv->ai_timer1 = 0;
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 0fd021062..49c8e21 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -1042,6 +1042,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 {
 	const struct boardtype *this_board = comedi_board(dev);
 	struct pci1710_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	unsigned int divisor1 = 0, divisor2 = 0;
@@ -1129,8 +1130,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 
 	/* step 5: complain about special chanlist considerations */
 
-	if (cmd->chanlist) {
-		if (!check_channel_list(dev, s, cmd->chanlist,
+	if (chanlist) {
+		if (!check_channel_list(dev, s, chanlist,
 					cmd->chanlist_len))
 			return 5;	/*  incorrect channels list */
 	}
@@ -1145,9 +1146,10 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pci1710_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 
 	devpriv->ai_n_chan = cmd->chanlist_len;
-	devpriv->ai_chanlist = cmd->chanlist;
+	devpriv->ai_chanlist = chanlist;
 	devpriv->ai_flags = cmd->flags;
 	devpriv->ai_data_len = s->async->prealloc_bufsz;
 	devpriv->ai_data = s->async->prealloc_buf;
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index b7cfc13a..0a7c745 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -581,6 +581,7 @@ static int dio200_start_intr(struct comedi_device *dev,
 	unsigned isn_bits;
 	struct dio200_subdev_intr *subpriv = s->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int retval = 0;
 
 	if (!subpriv->continuous && subpriv->stopcount == 0) {
@@ -591,9 +592,9 @@ static int dio200_start_intr(struct comedi_device *dev,
 	} else {
 		/* Determine interrupt sources to enable. */
 		isn_bits = 0;
-		if (cmd->chanlist) {
+		if (chanlist) {
 			for (n = 0; n < cmd->chanlist_len; n++)
-				isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+				isn_bits |= (1U << CR_CHAN(chanlist[n]));
 		}
 		isn_bits &= subpriv->valid_isns;
 		/* Enable interrupt sources. */
@@ -642,6 +643,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
 				   struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
+	unsigned int *chanlist = s->async->cmd.chanlist.kernel_data;
 	unsigned triggered;
 	unsigned intstat;
 	unsigned cur_enabled;
@@ -705,7 +707,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
 				val = 0;
 				len = s->async->cmd.chanlist_len;
 				for (n = 0; n < len; n++) {
-					ch = CR_CHAN(s->async->cmd.chanlist[n]);
+					ch = CR_CHAN(chanlist[n]);
 					if (triggered & (1U << ch))
 						val |= (1U << n);
 				}
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index 365f911..10c3d51 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -717,6 +717,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		  struct comedi_cmd *cmd)
 {
 	struct pci224_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	unsigned int tmp;
 
@@ -933,7 +934,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 
 	/* Step 5: check channel list. */
 
-	if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+	if (chanlist && (cmd->chanlist_len > 0)) {
 		unsigned int range;
 		enum { range_err = 1, dupchan_err = 2, };
 		unsigned errors;
@@ -946,16 +947,16 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		 *
 		 * Check the list has no duplicate channels.
 		 */
-		range = CR_RANGE(cmd->chanlist[0]);
+		range = CR_RANGE(chanlist[0]);
 		errors = 0;
 		tmp = 0;
 		for (n = 0; n < cmd->chanlist_len; n++) {
-			ch = CR_CHAN(cmd->chanlist[n]);
+			ch = CR_CHAN(chanlist[n]);
 			if (tmp & (1U << ch))
 				errors |= dupchan_err;
 
 			tmp |= (1U << ch);
-			if (CR_RANGE(cmd->chanlist[n]) != range)
+			if (CR_RANGE(chanlist[n]) != range)
 				errors |= range_err;
 
 		}
@@ -989,6 +990,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pci224_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int range;
 	unsigned int i, j;
 	unsigned int ch;
@@ -996,7 +998,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	unsigned long flags;
 
 	/* Cannot handle null/empty chanlist. */
-	if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
+	if (!chanlist || !cmd->chanlist_len)
 		return -EINVAL;
 
 
@@ -1004,11 +1006,11 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->ao_enab = 0;
 
 	for (i = 0; i < cmd->chanlist_len; i++) {
-		ch = CR_CHAN(cmd->chanlist[i]);
+		ch = CR_CHAN(chanlist[i]);
 		devpriv->ao_enab |= 1U << ch;
 		rank = 0;
 		for (j = 0; j < cmd->chanlist_len; j++) {
-			if (CR_CHAN(cmd->chanlist[j]) < ch)
+			if (CR_CHAN(chanlist[j]) < ch)
 				rank++;
 
 		}
@@ -1019,7 +1021,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
 
 	/* Determine range and polarity.  All channels the same.  */
-	range = CR_RANGE(cmd->chanlist[0]);
+	range = CR_RANGE(chanlist[0]);
 
 	/*
 	 * Set DAC range and polarity.
@@ -1163,6 +1165,8 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
 	const struct pci224_board *thisboard = comedi_board(dev);
 	struct pci224_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	short *array = data;
 	unsigned int length = num_bytes / sizeof(*array);
 	unsigned int offset;
@@ -1172,7 +1176,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
 	/* The hardware expects 16-bit numbers. */
 	shift = 16 - thisboard->ao_bits;
 	/* Channels will be all bipolar or all unipolar. */
-	if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
+	if ((devpriv->hwrange[CR_RANGE(chanlist[0])] &
 	     PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
 		/* Unipolar */
 		offset = 0;
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index 4c9f131..fdb881c 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -955,6 +955,7 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
 {
 	const struct pci230_board *thisboard = comedi_board(dev);
 	struct pci230_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	unsigned int tmp;
 
@@ -1117,7 +1118,7 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
 
 	/* Step 5: check channel list if it exists. */
 
-	if (cmd->chanlist && cmd->chanlist_len > 0) {
+	if (chanlist && cmd->chanlist_len > 0) {
 		enum {
 			seq_err = (1 << 0),
 			range_err = (1 << 1)
@@ -1127,12 +1128,12 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
 		unsigned int chan, prev_chan;
 		unsigned int range, first_range;
 
-		prev_chan = CR_CHAN(cmd->chanlist[0]);
-		first_range = CR_RANGE(cmd->chanlist[0]);
+		prev_chan = CR_CHAN(chanlist[0]);
+		first_range = CR_RANGE(chanlist[0]);
 		errors = 0;
 		for (n = 1; n < cmd->chanlist_len; n++) {
-			chan = CR_CHAN(cmd->chanlist[n]);
-			range = CR_RANGE(cmd->chanlist[n]);
+			chan = CR_CHAN(chanlist[n]);
+			range = CR_RANGE(chanlist[n]);
 			/* Channel numbers must strictly increase. */
 			if (chan < prev_chan)
 				errors |= seq_err;
@@ -1224,6 +1225,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev,
 	int i, ret;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 
 	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0))
 		return;
@@ -1237,7 +1239,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev,
 			return;
 		}
 		/* Write value to DAC. */
-		pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
+		pci230_ao_write_nofifo(dev, data, CR_CHAN(chanlist[i]));
 	}
 	async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
 	if (!devpriv->ao_continuous) {
@@ -1258,6 +1260,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
 	struct pci230_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int num_scans;
 	unsigned int room;
 	unsigned short dacstat;
@@ -1317,7 +1320,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
 
 				comedi_buf_get(async, &datum);
 				pci230_ao_write_fifo(dev, datum,
-						     CR_CHAN(cmd->chanlist[i]));
+						     CR_CHAN(chanlist[i]));
 			}
 		}
 		events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
@@ -1496,12 +1499,11 @@ static int pci230_ao_inttrig_start(struct comedi_device *dev,
 static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pci230_private *devpriv = dev->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned short daccon;
 	unsigned int range;
 
-	/* Get the command. */
-	struct comedi_cmd *cmd = &s->async->cmd;
-
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		/* Claim Z2-CT1. */
 		if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD))
@@ -1521,7 +1523,7 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	/* Set range - see analogue output range table; 0 => unipolar 10V,
 	 * 1 => bipolar +/-10V range scale */
-	range = CR_RANGE(cmd->chanlist[0]);
+	range = CR_RANGE(chanlist[0]);
 	devpriv->ao_bipolar = pci230_ao_bipolar[range];
 	daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
 	/* Use DAC FIFO for hardware version 2 onwards. */
@@ -1531,7 +1533,7 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 		dacen = 0;
 		for (i = 0; i < cmd->chanlist_len; i++)
-			dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
+			dacen |= 1 << CR_CHAN(chanlist[i]);
 
 		/* Set channel scan list. */
 		outw(dacen, dev->iobase + PCI230P2_DACEN);
@@ -1607,6 +1609,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
 {
 	const struct pci230_board *thisboard = comedi_board(dev);
 	struct pci230_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	unsigned int tmp;
 
@@ -1705,9 +1708,9 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
 		if (devpriv->hwver == 0) {
 			/* PCI230 or PCI260.  Max speed depends whether
 			 * single-ended or pseudo-differential. */
-			if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+			if (chanlist && (cmd->chanlist_len > 0)) {
 				/* Peek analogue reference of first channel. */
-				if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
+				if (CR_AREF(chanlist[0]) == AREF_DIFF)
 					max_speed_ai = MAX_SPEED_AI_DIFF;
 				else
 					max_speed_ai = MAX_SPEED_AI_SE;
@@ -1846,7 +1849,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
 
 	/* Step 5: check channel list if it exists. */
 
-	if (cmd->chanlist && cmd->chanlist_len > 0) {
+	if (chanlist && cmd->chanlist_len > 0) {
 		enum {
 			seq_err = 1 << 0,
 			rangepair_err = 1 << 1,
@@ -1867,9 +1870,9 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
 		errors = 0;
 		prev_chan = prev_aref = prev_range = prev_polarity = 0;
 		for (n = 0; n < cmd->chanlist_len; n++) {
-			chan = CR_CHAN(cmd->chanlist[n]);
-			range = CR_RANGE(cmd->chanlist[n]);
-			aref = CR_AREF(cmd->chanlist[n]);
+			chan = CR_CHAN(chanlist[n]);
+			range = CR_RANGE(chanlist[n]);
+			aref = CR_AREF(chanlist[n]);
 			polarity = pci230_ai_bipolar[range];
 			/* Only the first half of the channels are available if
 			 * differential.  (These are remapped in software.  In
@@ -1886,8 +1889,8 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
 					subseq_len = n;
 				}
 				if ((subseq_len > 0)
-				    && (cmd->chanlist[n] !=
-					cmd->chanlist[n % subseq_len])) {
+				    && (chanlist[n] !=
+					chanlist[n % subseq_len])) {
 					errors |= seq_err;
 				}
 				/* Channels must have same AREF. */
@@ -1936,7 +1939,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
 			 * does, and we can't tell them apart!
 			 */
 			if ((subseq_len > 1)
-			    && (CR_CHAN(cmd->chanlist[0]) != 0)) {
+			    && (CR_CHAN(chanlist[0]) != 0)) {
 				errors |= buggy_chan0_err;
 			}
 		}
@@ -2390,15 +2393,14 @@ static void pci230_handle_ai(struct comedi_device *dev,
 static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pci230_private *devpriv = dev->private;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int i, chan, range, diff;
 	unsigned int res_mask;
 	unsigned short adccon, adcen;
 	unsigned char zgat;
 
-	/* Get the command. */
-	struct comedi_async *async = s->async;
-	struct comedi_cmd *cmd = &async->cmd;
-
 	/*
 	 * Determine which shared resources are needed.
 	 */
@@ -2450,7 +2452,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	adccon = PCI230_ADC_FIFO_EN;
 	adcen = 0;
 
-	if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+	if (CR_AREF(chanlist[0]) == AREF_DIFF) {
 		/* Differential - all channels must be differential. */
 		diff = 1;
 		adccon |= PCI230_ADC_IM_DIF;
@@ -2460,7 +2462,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		adccon |= PCI230_ADC_IM_SE;
 	}
 
-	range = CR_RANGE(cmd->chanlist[0]);
+	range = CR_RANGE(chanlist[0]);
 	devpriv->ai_bipolar = pci230_ai_bipolar[range];
 	if (devpriv->ai_bipolar)
 		adccon |= PCI230_ADC_IR_BIP;
@@ -2470,8 +2472,8 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		unsigned int gainshift;
 
-		chan = CR_CHAN(cmd->chanlist[i]);
-		range = CR_RANGE(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		range = CR_RANGE(chanlist[i]);
 		if (diff) {
 			gainshift = 2 * chan;
 			if (devpriv->hwver == 0) {
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 4dd87c2..7ffde2b 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -799,6 +799,7 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
 {
 	const struct cb_pcidas_board *thisboard = comedi_board(dev);
 	struct cb_pcidas_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	int i, gain, start_chan;
@@ -940,17 +941,17 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
 		return 4;
 
 	/*  check channel/gain list against card's limitations */
-	if (cmd->chanlist) {
-		gain = CR_RANGE(cmd->chanlist[0]);
-		start_chan = CR_CHAN(cmd->chanlist[0]);
+	if (chanlist) {
+		gain = CR_RANGE(chanlist[0]);
+		start_chan = CR_CHAN(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) !=
+			if (CR_CHAN(chanlist[i]) !=
 			    (start_chan + i) % s->n_chan) {
 				comedi_error(dev,
 					     "entries in chanlist must be consecutive channels, counting upwards\n");
 				err++;
 			}
-			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+			if (CR_RANGE(chanlist[i]) != gain) {
 				comedi_error(dev,
 					     "entries in chanlist must all have the same gain\n");
 				err++;
@@ -987,6 +988,7 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev,
 	struct cb_pcidas_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int bits;
 	unsigned long flags;
 
@@ -998,14 +1000,14 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev,
 	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
 
 	/*  set mux limits, gain and pacer source */
-	bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
-	    END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
-	    GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
+	bits = BEGIN_SCAN(CR_CHAN(chanlist[0])) |
+	    END_SCAN(CR_CHAN(chanlist[cmd->chanlist_len - 1])) |
+	    GAIN_BITS(CR_RANGE(chanlist[0]));
 	/*  set unipolar/bipolar */
-	if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
+	if (CR_RANGE(chanlist[0]) & IS_UNIPOLAR)
 		bits |= UNIP;
 	/*  set singleended/differential */
-	if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
+	if (CR_AREF(chanlist[0]) != AREF_DIFF)
 		bits |= SE;
 	/*  set pacer source */
 	if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
@@ -1076,6 +1078,7 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
 {
 	const struct cb_pcidas_board *thisboard = comedi_board(dev);
 	struct cb_pcidas_private *devpriv = dev->private;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 
@@ -1166,9 +1169,9 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
 		return 4;
 
 	/*  check channel/gain list against card's limitations */
-	if (cmd->chanlist && cmd->chanlist_len > 1) {
-		if (CR_CHAN(cmd->chanlist[0]) != 0 ||
-		    CR_CHAN(cmd->chanlist[1]) != 1) {
+	if (chanlist && cmd->chanlist_len > 1) {
+		if (CR_CHAN(chanlist[0]) != 0 ||
+		    CR_CHAN(chanlist[1]) != 1) {
 			comedi_error(dev,
 				     "channels must be ordered channel 0, channel 1 in chanlist\n");
 			err++;
@@ -1254,6 +1257,7 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
 	struct cb_pcidas_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int i;
 	unsigned long flags;
 
@@ -1262,11 +1266,10 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		/*  enable channel */
 		devpriv->ao_control_bits |=
-		    DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
+		    DAC_CHAN_EN(CR_CHAN(chanlist[i]));
 		/*  set range */
-		devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
-						      CR_RANGE(cmd->
-							       chanlist[i]));
+		devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(chanlist[i]),
+						      CR_RANGE(chanlist[i]));
 	}
 
 	/*  disable analog out before settings pacer source and count values */
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 7168883..585917d 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -2107,6 +2107,7 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		      struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	unsigned int tmp_arg, tmp_arg2;
@@ -2253,10 +2254,10 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		return 4;
 
 	/*  make sure user is doesn't change analog reference mid chanlist */
-	if (cmd->chanlist) {
-		aref = CR_AREF(cmd->chanlist[0]);
+	if (chanlist) {
+		aref = CR_AREF(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (aref != CR_AREF(cmd->chanlist[i])) {
+			if (aref != CR_AREF(chanlist[i])) {
 				comedi_error(dev,
 					     "all elements in chanlist must use the same analog reference");
 				err++;
@@ -2265,9 +2266,9 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		}
 		/*  check 4020 chanlist */
 		if (board(dev)->layout == LAYOUT_4020) {
-			unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+			unsigned int first_channel = CR_CHAN(chanlist[0]);
 			for (i = 1; i < cmd->chanlist_len; i++) {
-				if (CR_CHAN(cmd->chanlist[i]) !=
+				if (CR_CHAN(chanlist[i]) !=
 				    first_channel + i) {
 					comedi_error(dev,
 						     "chanlist must use consecutive channels");
@@ -2518,15 +2519,15 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
 
 static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int i;
+
 	for (i = 0; i + 1 < cmd->chanlist_len; i++) {
-		if (CR_CHAN(cmd->chanlist[i + 1]) !=
-		    CR_CHAN(cmd->chanlist[i]) + 1)
+		if (CR_CHAN(chanlist[i + 1]) != CR_CHAN(chanlist[i]) + 1)
 			return 0;
-		if (CR_RANGE(cmd->chanlist[i + 1]) !=
-		    CR_RANGE(cmd->chanlist[i]))
+		if (CR_RANGE(chanlist[i + 1]) != CR_RANGE(chanlist[i]))
 			return 0;
-		if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
+		if (CR_AREF(chanlist[i + 1]) != CR_AREF(chanlist[i]))
 			return 0;
 	}
 	return 1;
@@ -2535,6 +2536,7 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
 static int setup_channel_queue(struct comedi_device *dev,
 			       const struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned short bits;
 	int i;
 
@@ -2545,19 +2547,19 @@ static int setup_channel_queue(struct comedi_device *dev,
 			       priv(dev)->main_iobase + HW_CONFIG_REG);
 			bits = 0;
 			/*  set channel */
-			bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
+			bits |= adc_chan_bits(CR_CHAN(chanlist[0]));
 			/*  set gain */
 			bits |= ai_range_bits_6xxx(dev,
-						   CR_RANGE(cmd->chanlist[0]));
+						   CR_RANGE(chanlist[0]));
 			/*  set single-ended / differential */
 			bits |= se_diff_bit_6xxx(dev,
-						 CR_AREF(cmd->chanlist[0]) ==
+						 CR_AREF(chanlist[0]) ==
 						 AREF_DIFF);
-			if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
+			if (CR_AREF(chanlist[0]) == AREF_COMMON)
 				bits |= ADC_COMMON_BIT;
 			/*  set stop channel */
 			writew(adc_chan_bits
-			       (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
+			       (CR_CHAN(chanlist[cmd->chanlist_len - 1])),
 			       priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
 			/*  set start channel, and rest of settings */
 			writew(bits,
@@ -2581,18 +2583,14 @@ static int setup_channel_queue(struct comedi_device *dev,
 				bits = 0;
 				/*  set channel */
 				bits |=
-				    adc_chan_bits(CR_CHAN(cmd->chanlist[i]));
+				    adc_chan_bits(CR_CHAN(chanlist[i]));
 				/*  set gain */
 				bits |= ai_range_bits_6xxx(dev,
-							   CR_RANGE(cmd->
-								    chanlist
-								    [i]));
+							CR_RANGE(chanlist[i]));
 				/*  set single-ended / differential */
 				bits |= se_diff_bit_6xxx(dev,
-							 CR_AREF(cmd->
-								 chanlist[i]) ==
-							 AREF_DIFF);
-				if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
+					CR_AREF(chanlist[i]) == AREF_DIFF);
+				if (CR_AREF(chanlist[i]) == AREF_COMMON)
 					bits |= ADC_COMMON_BIT;
 				/*  mark end of queue */
 				if (i == cmd->chanlist_len - 1)
@@ -2620,8 +2618,8 @@ static int setup_channel_queue(struct comedi_device *dev,
 		priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
 		/*  select ranges */
 		for (i = 0; i < cmd->chanlist_len; i++) {
-			unsigned int channel = CR_CHAN(cmd->chanlist[i]);
-			unsigned int range = CR_RANGE(cmd->chanlist[i]);
+			unsigned int channel = CR_CHAN(chanlist[i]);
+			unsigned int range = CR_RANGE(chanlist[i]);
 
 			if (range == 0)
 				priv(dev)->i2c_cal_range_bits |=
@@ -2672,6 +2670,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	uint32_t bits;
 	unsigned int i;
 	unsigned long flags;
@@ -2711,12 +2710,10 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
 		priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
 		priv(dev)->adc_control1_bits |=
-		    adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
+		    adc_lo_chan_4020_bits(CR_CHAN(chanlist[0]));
 		priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
 		priv(dev)->adc_control1_bits |=
-		    adc_hi_chan_4020_bits(CR_CHAN
-					  (cmd->
-					   chanlist[cmd->chanlist_len - 1]));
+		    adc_hi_chan_4020_bits(CR_CHAN(chanlist[cmd->chanlist_len - 1]));
 	}
 	writew(priv(dev)->adc_control1_bits,
 	       priv(dev)->main_iobase + ADC_CONTROL1_REG);
@@ -3250,13 +3247,14 @@ static void set_dac_control0_reg(struct comedi_device *dev,
 static void set_dac_control1_reg(struct comedi_device *dev,
 				 const struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int i;
 
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		int channel, range;
 
-		channel = CR_CHAN(cmd->chanlist[i]);
-		range = CR_RANGE(cmd->chanlist[i]);
+		channel = CR_CHAN(chanlist[i]);
+		range = CR_RANGE(chanlist[i]);
 		set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
 				   range);
 	}
@@ -3268,11 +3266,12 @@ static void set_dac_control1_reg(struct comedi_device *dev,
 static void set_dac_select_reg(struct comedi_device *dev,
 			       const struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	uint16_t bits;
 	unsigned int first_channel, last_channel;
 
-	first_channel = CR_CHAN(cmd->chanlist[0]);
-	last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+	first_channel = CR_CHAN(chanlist[0]);
+	last_channel = CR_CHAN(chanlist[cmd->chanlist_len - 1]);
 	if (last_channel < first_channel)
 		comedi_error(dev, "bug! last ao channel < first ao channel");
 
@@ -3465,6 +3464,7 @@ static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		      struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	unsigned int tmp_arg;
@@ -3559,10 +3559,10 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	if (err)
 		return 4;
 
-	if (cmd->chanlist) {
-		unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+	if (chanlist) {
+		unsigned int first_channel = CR_CHAN(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) != first_channel + i) {
+			if (CR_CHAN(chanlist[i]) != first_channel + i) {
 				comedi_error(dev,
 					     "chanlist must use consecutive channels");
 				err++;
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index b0f0ec5..10fe57d 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -171,6 +171,7 @@ static void waveform_ai_interrupt(unsigned long arg)
 	struct waveform_private *devpriv = dev->private;
 	struct comedi_async *async = dev->read_subdev->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int i, j;
 	/* all times in microsec */
 	unsigned long elapsed_time;
@@ -192,18 +193,12 @@ static void waveform_ai_interrupt(unsigned long arg)
 	for (i = 0; i < num_scans; i++) {
 		for (j = 0; j < cmd->chanlist_len; j++) {
 			cfc_write_to_buffer(dev->read_subdev,
-					    fake_waveform(dev,
-							  CR_CHAN(cmd->
-								  chanlist[j]),
-							  CR_RANGE(cmd->
-								   chanlist[j]),
-							  devpriv->
-							  usec_current +
-							  i *
-							  devpriv->scan_period +
-							  j *
-							  devpriv->
-							  convert_period));
+					fake_waveform(dev,
+						CR_CHAN(chanlist[j]),
+						CR_RANGE(chanlist[j]),
+						devpriv->usec_current +
+						i * devpriv->scan_period +
+						j * devpriv->convert_period));
 		}
 		devpriv->ai_count++;
 		if (cmd->stop_src == TRIG_COUNT
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 2a38915..fed96bf 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -398,6 +398,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 			  struct comedi_cmd *cmd)
 {
 	const struct das16_board *board = comedi_board(dev);
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0, tmp;
 	int gain, start_chan, i;
 	int mask;
@@ -530,11 +531,11 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 		return 4;
 
 	/*  check channel/gain list against card's limitations */
-	if (cmd->chanlist) {
-		gain = CR_RANGE(cmd->chanlist[0]);
-		start_chan = CR_CHAN(cmd->chanlist[0]);
+	if (chanlist) {
+		gain = CR_RANGE(chanlist[0]);
+		start_chan = CR_CHAN(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) !=
+			if (CR_CHAN(chanlist[i]) !=
 			    (start_chan + i) % s->n_chan) {
 				comedi_error(dev,
 						"entries in chanlist must be "
@@ -542,7 +543,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 						"counting upwards\n");
 				err++;
 			}
-			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+			if (CR_RANGE(chanlist[i]) != gain) {
 				comedi_error(dev,
 						"entries in chanlist must all "
 						"have the same gain\n");
@@ -617,6 +618,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 	const struct das16_board *board = comedi_board(dev);
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int byte;
 	unsigned long flags;
 	int range;
@@ -642,15 +644,15 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 		outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
 
 	/*  set scan limits */
-	byte = CR_CHAN(cmd->chanlist[0]);
-	byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
+	byte = CR_CHAN(chanlist[0]);
+	byte |= CR_CHAN(chanlist[cmd->chanlist_len - 1]) << 4;
 	outb(byte, dev->iobase + DAS16_MUX);
 
 	/* set gain (this is also burst rate register but according to
 	 * computer boards manual, burst rate does nothing, even on
 	 * keithley cards) */
 	if (board->ai_pg != das16_pg_none) {
-		range = CR_RANGE(cmd->chanlist[0]);
+		range = CR_RANGE(chanlist[0]);
 		outb((das16_gainlists[board->ai_pg])[range],
 		     dev->iobase + DAS16_GAIN);
 	}
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index 7f0668f..f82bfeb1 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -168,6 +168,7 @@ static int das16m1_cmd_test(struct comedi_device *dev,
 			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	const struct das16m1_board *board = comedi_board(dev);
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int err = 0, tmp, i;
 
 	/* make sure triggers are valid */
@@ -267,10 +268,10 @@ static int das16m1_cmd_test(struct comedi_device *dev,
 		return 4;
 
 	/*  check chanlist against board's peculiarities */
-	if (cmd->chanlist && cmd->chanlist_len > 1) {
+	if (chanlist && cmd->chanlist_len > 1) {
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			/*  even/odd channels must go into even/odd queue addresses */
-			if ((i % 2) != (CR_CHAN(cmd->chanlist[i]) % 2)) {
+			if ((i % 2) != (CR_CHAN(chanlist[i]) % 2)) {
 				comedi_error(dev, "bad chanlist:\n"
 					     " even/odd channels must go have even/odd chanlist indices");
 				err++;
@@ -313,6 +314,7 @@ static int das16m1_cmd_exec(struct comedi_device *dev,
 {
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int byte, i;
 
 	if (dev->irq == 0) {
@@ -337,9 +339,8 @@ static int das16m1_cmd_exec(struct comedi_device *dev,
 	/* setup channel/gain queue */
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
-		byte =
-		    Q_CHAN(CR_CHAN(cmd->chanlist[i])) |
-		    Q_RANGE(CR_RANGE(cmd->chanlist[i]));
+		byte = Q_CHAN(CR_CHAN(chanlist[i])) |
+		       Q_RANGE(CR_RANGE(chanlist[i]));
 		outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
 	}
 
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 5aca8fb..51c331f 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -783,6 +783,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
 				 struct comedi_subdevice *s,
 				 struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	unsigned int tmp_arg;
@@ -939,10 +940,10 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
 		return 4;
 
 	/*  make sure user is not trying to mix unipolar and bipolar ranges */
-	if (cmd->chanlist) {
-		unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
+	if (chanlist) {
+		unipolar = CR_RANGE(chanlist[0]) & UNIPOLAR;
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
+			if (unipolar != (CR_RANGE(chanlist[i]) & UNIPOLAR)) {
 				comedi_error(dev,
 					     "unipolar and bipolar ranges cannot be mixed in the chanlist");
 				err++;
@@ -982,20 +983,21 @@ static int control_a_bits(struct comedi_cmd cmd)
 /* returns appropriate bits for control register c, depending on command */
 static int control_c_bits(struct comedi_cmd cmd)
 {
+	unsigned int *chanlist = cmd.chanlist.kernel_data;
 	int control_c;
 	int aref;
 
 	/* set clock source to internal or external, select analog reference,
 	 * select unipolar / bipolar
 	 */
-	aref = CR_AREF(cmd.chanlist[0]);
+	aref = CR_AREF(chanlist[0]);
 	control_c = UQEN;	/* enable upper qram addresses */
 	if (aref != AREF_DIFF)
 		control_c |= SD;
 	if (aref == AREF_COMMON)
 		control_c |= CMEN;
 	/* if a unipolar range was selected */
-	if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
+	if (CR_RANGE(chanlist[0]) & UNIPOLAR)
 		control_c |= UB;
 	switch (cmd.scan_begin_src) {
 	case TRIG_FOLLOW:	/*  not in burst mode */
@@ -1165,6 +1167,7 @@ static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
 /* programs channel/gain list into card */
 static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
 {
+	unsigned int *chanlist = cmd.chanlist.kernel_data;
 	int i, n, chan_range;
 	unsigned long irq_flags;
 	const int range_mask = 0x3;	/* masks unipolar/bipolar bit off range */
@@ -1177,10 +1180,9 @@ static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
 	outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);	/*set QRAM address start */
 	/* make channel / gain list */
 	for (i = 0; i < n; i++) {
-		chan_range =
-		    CR_CHAN(cmd.
-			    chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) &
-					     range_mask) << range_bitshift);
+		chan_range = CR_CHAN(chanlist[i]) |
+			     ((CR_RANGE(chanlist[i]) &
+			     range_mask) << range_bitshift);
 		outw(chan_range, dev->iobase + DAS1800_QRAM);
 	}
 	outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);	/*finish write to QRAM */
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 8e89101..8a94c89 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -604,6 +604,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
 				struct comedi_subdevice *s,
 				struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	int gain, startChan;
@@ -703,17 +704,17 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
 		return 4;
 
 	/*  check channel/gain list against card's limitations */
-	if (cmd->chanlist) {
-		gain = CR_RANGE(cmd->chanlist[0]);
-		startChan = CR_CHAN(cmd->chanlist[0]);
+	if (chanlist) {
+		gain = CR_RANGE(chanlist[0]);
+		startChan = CR_CHAN(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) !=
+			if (CR_CHAN(chanlist[i]) !=
 			    (startChan + i) % N_CHAN_AI) {
 				comedi_error(dev,
 					     "entries in chanlist must be consecutive channels, counting upwards\n");
 				err++;
 			}
-			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+			if (CR_RANGE(chanlist[i]) != gain) {
 				comedi_error(dev,
 					     "entries in chanlist must all have the same gain\n");
 				err++;
@@ -734,6 +735,7 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
 	int conv_bits;
 	unsigned long irq_flags;
 	struct comedi_async *async = s->async;
+	unsigned int *chanlist = async->cmd.chanlist.kernel_data;
 
 	if (!dev->irq) {
 		comedi_error(dev,
@@ -744,7 +746,7 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
 	disable_das800(dev);
 
 	/* set channel scan limits */
-	startChan = CR_CHAN(async->cmd.chanlist[0]);
+	startChan = CR_CHAN(chanlist[0]);
 	endChan = (startChan + async->cmd.chanlist_len - 1) % 8;
 	scan = (endChan << 3) | startChan;
 
@@ -754,7 +756,7 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
 	spin_unlock_irqrestore(&dev->spinlock, irq_flags);
 
 	/* set gain */
-	gain = CR_RANGE(async->cmd.chanlist[0]);
+	gain = CR_RANGE(chanlist[0]);
 	if (thisboard->resolution == 12 && gain > 0)
 		gain += 0x7;
 	gain &= 0xf;
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 0703ca5..5a602a6 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -254,6 +254,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
 			      struct comedi_subdevice *s,
 			      struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	int start_chan, gain, i;
@@ -403,17 +404,17 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
 	/* step 5 check the channel list, the channel list for this
 	   board must be consecutive and gains must be the same */
 
-	if (cmd->chanlist) {
-		gain = CR_RANGE(cmd->chanlist[0]);
-		start_chan = CR_CHAN(cmd->chanlist[0]);
+	if (chanlist) {
+		gain = CR_RANGE(chanlist[0]);
+		start_chan = CR_CHAN(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) !=
+			if (CR_CHAN(chanlist[i]) !=
 			    (start_chan + i) % s->n_chan) {
 				comedi_error(dev,
 					     "entries in chanlist must be consecutive channels, counting upwards\n");
 				err++;
 			}
-			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+			if (CR_RANGE(chanlist[i]) != gain) {
 				comedi_error(dev,
 					     "entries in chanlist must all have the same gain\n");
 				err++;
@@ -461,18 +462,19 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct dmm32at_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int i, range;
 	unsigned char chanlo, chanhi, status;
 
-	if (!cmd->chanlist)
+	if (!chanlist)
 		return -EINVAL;
 
 	/* get the channel list and range */
-	chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1);
+	chanlo = CR_CHAN(chanlist[0]) & (s->n_chan - 1);
 	chanhi = chanlo + cmd->chanlist_len - 1;
 	if (chanhi >= s->n_chan)
 		return -EINVAL;
-	range = CR_RANGE(cmd->chanlist[0]);
+	range = CR_RANGE(chanlist[0]);
 
 	/* reset fifo */
 	outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL);
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index ce5d837..dde4b16 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -219,6 +219,7 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev,
 static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int chan;
 	int trigvar;
 
@@ -226,7 +227,7 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	    dt2814_ns_to_timer(&cmd->scan_begin_arg,
 			       cmd->flags & TRIG_ROUND_MASK);
 
-	chan = CR_CHAN(cmd->chanlist[0]);
+	chan = CR_CHAN(chanlist[0]);
 
 	devpriv->ntrig = cmd->stop_arg;
 	outb(chan | DT2814_ENB | (trigvar << 5), dev->iobase + DT2814_CSR);
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index b7c43c8..cca9df5 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -695,6 +695,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	const struct dt282x_board *board = comedi_board(dev);
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int timer;
 
 	if (devpriv->usedma == 0) {
@@ -735,7 +736,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	devpriv->adcsr = 0;
 
-	dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
+	dt282x_load_changain(dev, cmd->chanlist_len, chanlist);
 
 	devpriv->adcsr = DT2821_ADCLK | DT2821_IADDONE;
 	outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 3a940a2..ac83adf 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -567,6 +567,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
 static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int i;
 	unsigned int chan, range, aref;
 	unsigned int divider;
@@ -576,13 +577,13 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	dev_dbg(dev->class_dev, "dt3k_ai_cmd:\n");
 	for (i = 0; i < cmd->chanlist_len; i++) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		range = CR_RANGE(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		range = CR_RANGE(chanlist[i]);
 
 		writew((range << 6) | chan,
 		       devpriv->io_addr + DPR_ADC_buffer + i);
 	}
-	aref = CR_AREF(cmd->chanlist[0]);
+	aref = CR_AREF(chanlist[0]);
 
 	writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
 	dev_dbg(dev->class_dev, "param[0]=0x%04x\n", cmd->scan_end_arg);
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 5d3fa71..4585a55 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -722,6 +722,7 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data)
 static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 		       struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	int i;
@@ -802,11 +803,11 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 	if (err)
 		return 4;
 
-	if (!cmd->chanlist)
+	if (!chanlist)
 		return 0;
 
 	for (i = 1; i < cmd->chanlist_len; i++) {
-		if (CR_CHAN(cmd->chanlist[i]) != i) {
+		if (CR_CHAN(chanlist[i]) != i) {
 			/*  XXX could support 8 or 16 channels */
 			comedi_error(dev,
 				     "chanlist must be ch 0 to 31 in order");
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index d7c5146..86e4c9e 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -624,6 +624,7 @@ static int ai_check_chanlist(struct comedi_device *dev,
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	const struct me4000_board *thisboard = comedi_board(dev);
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int aref;
 	int i;
 
@@ -640,15 +641,15 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	}
 
 	/* Check the pointer */
-	if (!cmd->chanlist) {
+	if (!chanlist) {
 		dev_err(dev->class_dev, "NULL pointer to channel list\n");
 		return -EFAULT;
 	}
 
 	/* Check whether aref is equal for all entries */
-	aref = CR_AREF(cmd->chanlist[0]);
+	aref = CR_AREF(chanlist[0]);
 	for (i = 0; i < cmd->chanlist_len; i++) {
-		if (CR_AREF(cmd->chanlist[i]) != aref) {
+		if (CR_AREF(chanlist[i]) != aref) {
 			dev_err(dev->class_dev,
 				"Mode is not equal for all entries\n");
 			return -EINVAL;
@@ -658,7 +659,7 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	/* Check whether channels are available for this ending */
 	if (aref == SDF_DIFF) {
 		for (i = 0; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) >=
+			if (CR_CHAN(chanlist[i]) >=
 			    thisboard->ai_diff_nchan) {
 				dev_err(dev->class_dev,
 					"Channel number to high\n");
@@ -667,7 +668,7 @@ static int ai_check_chanlist(struct comedi_device *dev,
 		}
 	} else {
 		for (i = 0; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
+			if (CR_CHAN(chanlist[i]) >= thisboard->ai_nchan) {
 				dev_err(dev->class_dev,
 					"Channel number to high\n");
 				return -EINVAL;
@@ -678,8 +679,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	/* Check if bipolar is set for all entries when in differential mode */
 	if (aref == SDF_DIFF) {
 		for (i = 0; i < cmd->chanlist_len; i++) {
-			if (CR_RANGE(cmd->chanlist[i]) != 1 &&
-			    CR_RANGE(cmd->chanlist[i]) != 2) {
+			if (CR_RANGE(chanlist[i]) != 1 &&
+			    CR_RANGE(chanlist[i]) != 2) {
 				dev_err(dev->class_dev,
 				       "Bipolar is not selected in differential mode\n");
 				return -EINVAL;
@@ -764,6 +765,7 @@ static void ai_write_timer(struct comedi_device *dev,
 static int ai_write_chanlist(struct comedi_device *dev,
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int entry;
 	unsigned int chan;
 	unsigned int rang;
@@ -771,9 +773,9 @@ static int ai_write_chanlist(struct comedi_device *dev,
 	int i;
 
 	for (i = 0; i < cmd->chanlist_len; i++) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		rang = CR_RANGE(cmd->chanlist[i]);
-		aref = CR_AREF(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		rang = CR_RANGE(chanlist[i]);
+		aref = CR_AREF(chanlist[i]);
 
 		entry = chan;
 
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 5895d4d..6bd8c10 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -316,6 +316,7 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 static int a2150_ai_cmdtest(struct comedi_device *dev,
 			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	int startChan;
@@ -412,16 +413,16 @@ static int a2150_ai_cmdtest(struct comedi_device *dev,
 		return 4;
 
 	/*  check channel/gain list against card's limitations */
-	if (cmd->chanlist) {
-		startChan = CR_CHAN(cmd->chanlist[0]);
+	if (chanlist) {
+		startChan = CR_CHAN(chanlist[0]);
 		for (i = 1; i < cmd->chanlist_len; i++) {
-			if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
+			if (CR_CHAN(chanlist[i]) != (startChan + i)) {
 				comedi_error(dev,
 					     "entries in chanlist must be consecutive channels, counting upwards\n");
 				err++;
 			}
 		}
-		if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
+		if (cmd->chanlist_len == 2 && CR_CHAN(chanlist[0]) == 1) {
 			comedi_error(dev,
 				     "length 2 chanlist must be channels 0,1 or channels 2,3");
 			err++;
@@ -431,8 +432,8 @@ static int a2150_ai_cmdtest(struct comedi_device *dev,
 				     "chanlist must have 1,2 or 4 channels");
 			err++;
 		}
-		if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
-		    CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
+		if (CR_AREF(chanlist[0]) != CR_AREF(chanlist[1]) ||
+		    CR_AREF(chanlist[2]) != CR_AREF(chanlist[3])) {
 			comedi_error(dev,
 				     "channels 0/1 and 2/3 must have the same analog reference");
 			err++;
@@ -449,6 +450,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned long lock_flags;
 	unsigned int old_config_bits = devpriv->config_bits;
 	unsigned int trigger_bits;
@@ -467,16 +469,15 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	outw(0, dev->iobase + FIFO_RESET_REG);
 
 	/* setup chanlist */
-	if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
-			       cmd->chanlist_len) < 0)
+	if (a2150_set_chanlist(dev, CR_CHAN(chanlist[0]), cmd->chanlist_len) < 0)
 		return -1;
 
 	/*  setup ac/dc coupling */
-	if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
+	if (CR_AREF(chanlist[0]) == AREF_OTHER)
 		devpriv->config_bits |= AC0_BIT;
 	else
 		devpriv->config_bits &= ~AC0_BIT;
-	if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
+	if (CR_AREF(chanlist[2]) == AREF_OTHER)
 		devpriv->config_bits |= AC1_BIT;
 	else
 		devpriv->config_bits &= ~AC1_BIT;
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index 4108cbf..215d4ed 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -346,6 +346,7 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
 			   struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int timer, base_clock;
 	unsigned int sample_count, tmp, chan, gain;
 	int i;
@@ -369,8 +370,8 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
 
 	/* Setup the Mux-Gain Counter */
 	for (i = 0; i < cmd->chanlist_len; ++i) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		gain = CR_RANGE(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		gain = CR_RANGE(chanlist[i]);
 		outw(i, dev->iobase + MUX_CNTR_REG);
 		tmp = chan | (gain << 6);
 		if (i == cmd->scan_end_arg - 1)
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 295ddbb..a71757d 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -818,20 +818,22 @@ static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 
 static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
+
 	if (cmd->chanlist_len == 1)
 		return MODE_SINGLE_CHAN;
 
 	/* chanlist may be NULL during cmdtest. */
-	if (cmd->chanlist == NULL)
+	if (!chanlist)
 		return MODE_MULT_CHAN_UP;
 
-	if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
+	if (CR_CHAN(chanlist[0]) == CR_CHAN(chanlist[1]))
 		return MODE_SINGLE_CHAN_INTERVAL;
 
-	if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
+	if (CR_CHAN(chanlist[0]) < CR_CHAN(chanlist[1]))
 		return MODE_MULT_CHAN_UP;
 
-	if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
+	if (CR_CHAN(chanlist[0]) > CR_CHAN(chanlist[1]))
 		return MODE_MULT_CHAN_DOWN;
 
 	pr_err("ni_labpc: bug! cannot determine AI scan mode\n");
@@ -841,9 +843,10 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
 static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
 				     const struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int mode, channel, range, aref, i;
 
-	if (cmd->chanlist == NULL)
+	if (!chanlist)
 		return 0;
 
 	mode = labpc_ai_scan_mode(cmd);
@@ -859,29 +862,29 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
 		}
 	}
 
-	channel = CR_CHAN(cmd->chanlist[0]);
-	range = CR_RANGE(cmd->chanlist[0]);
-	aref = CR_AREF(cmd->chanlist[0]);
+	channel = CR_CHAN(chanlist[0]);
+	range = CR_RANGE(chanlist[0]);
+	aref = CR_AREF(chanlist[0]);
 
 	for (i = 0; i < cmd->chanlist_len; i++) {
 
 		switch (mode) {
 		case MODE_SINGLE_CHAN_INTERVAL:
-			if (CR_CHAN(cmd->chanlist[i]) != channel) {
+			if (CR_CHAN(chanlist[i]) != channel) {
 				comedi_error(dev,
 					     "channel scanning order specified in chanlist is not supported by hardware.\n");
 				return 1;
 			}
 			break;
 		case MODE_MULT_CHAN_UP:
-			if (CR_CHAN(cmd->chanlist[i]) != i) {
+			if (CR_CHAN(chanlist[i]) != i) {
 				comedi_error(dev,
 					     "channel scanning order specified in chanlist is not supported by hardware.\n");
 				return 1;
 			}
 			break;
 		case MODE_MULT_CHAN_DOWN:
-			if (CR_CHAN(cmd->chanlist[i]) !=
+			if (CR_CHAN(chanlist[i]) !=
 			    cmd->chanlist_len - i - 1) {
 				comedi_error(dev,
 					     "channel scanning order specified in chanlist is not supported by hardware.\n");
@@ -895,13 +898,13 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
 			break;
 		}
 
-		if (CR_RANGE(cmd->chanlist[i]) != range) {
+		if (CR_RANGE(chanlist[i]) != range) {
 			comedi_error(dev,
 				     "entries in chanlist must all have the same range\n");
 			return 1;
 		}
 
-		if (CR_AREF(cmd->chanlist[i]) != aref) {
+		if (CR_AREF(chanlist[i]) != aref) {
 			comedi_error(dev,
 				     "entries in chanlist must all have the same reference\n");
 			return 1;
@@ -1121,6 +1124,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	int ret;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	enum transfer_type xfer;
 	unsigned long flags;
 
@@ -1129,8 +1133,8 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		return -1;
 	}
 
-	range = CR_RANGE(cmd->chanlist[0]);
-	aref = CR_AREF(cmd->chanlist[0]);
+	range = CR_RANGE(chanlist[0]);
+	aref = CR_AREF(chanlist[0]);
 
 	/* make sure board is disabled before setting up acquisition */
 	spin_lock_irqsave(&dev->spinlock, flags);
@@ -1223,9 +1227,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/* setup channel list, etc (command1 register) */
 	devpriv->command1_bits = 0;
 	if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
-		channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+		channel = CR_CHAN(chanlist[cmd->chanlist_len - 1]);
 	else
-		channel = CR_CHAN(cmd->chanlist[0]);
+		channel = CR_CHAN(chanlist[0]);
 	/* munge channel bits for differential / scan disabled mode */
 	if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
 		channel *= 2;
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 87995da..51ff34c 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -1260,6 +1260,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
 {
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int chan;
 	int i;
 	short d;
@@ -1273,7 +1274,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
 		if (err == 0)
 			break;
 
-		range = CR_RANGE(cmd->chanlist[chan]);
+		range = CR_RANGE(chanlist[chan]);
 
 		if (boardtype.reg_type & ni_reg_6xxx_mask) {
 			packed_data = d & 0xffff;
@@ -2382,6 +2383,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	const struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int timer;
 	int mode1 = 0;		/* mode1 is needed for both stop and convert */
 	int mode2 = 0;
@@ -2396,7 +2398,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	}
 	ni_clear_ai_fifo(dev);
 
-	ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+	ni_load_channelgain_list(dev, cmd->chanlist_len, chanlist);
 
 	/* start configuration */
 	devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
@@ -2858,6 +2860,8 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
 			unsigned int chan_index)
 {
 	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int range;
 	unsigned int i;
 	unsigned int offset;
@@ -2866,14 +2870,14 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
 
 	offset = 1 << (boardtype.aobits - 1);
 	for (i = 0; i < length; i++) {
-		range = CR_RANGE(async->cmd.chanlist[chan_index]);
+		range = CR_RANGE(chanlist[chan_index]);
 		if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
 			array[i] -= offset;
 #ifdef PCIDMA
 		array[i] = cpu_to_le16(array[i]);
 #endif
 		chan_index++;
-		chan_index %= async->cmd.chanlist_len;
+		chan_index %= cmd->chanlist_len;
 	}
 }
 
@@ -3152,6 +3156,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	const struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int bits;
 	int i;
 	unsigned trigvar;
@@ -3172,14 +3177,14 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			int chan;
 
-			chan = CR_CHAN(cmd->chanlist[i]);
+			chan = CR_CHAN(chanlist[i]);
 			bits |= 1 << chan;
 			ao_win_out(chan, AO_Waveform_Generation_611x);
 		}
 		ao_win_out(bits, AO_Timed_611x);
 	}
 
-	ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
+	ni_ao_config_chanlist(dev, s, chanlist, cmd->chanlist_len, 1);
 
 	if (cmd->stop_src == TRIG_NONE) {
 		devpriv->ao_mode1 |= AO_Continuous;
@@ -3301,7 +3306,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			bits |= AO_Number_Of_Channels(0);
 		} else {
 			bits |=
-			    AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]));
+			    AO_Number_Of_Channels(CR_CHAN(chanlist[0]));
 		}
 		devpriv->stc_writew(dev, bits, AO_Output_Control_Register);
 	}
@@ -3643,6 +3648,7 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
 static int ni_cdio_cmdtest(struct comedi_device *dev,
 			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp;
 	int sources;
@@ -3739,7 +3745,7 @@ static int ni_cdio_cmdtest(struct comedi_device *dev,
 	/* step 5: check chanlist */
 
 	for (i = 0; i < cmd->chanlist_len; ++i) {
-		if (cmd->chanlist[i] != i)
+		if (chanlist[i] != i)
 			err = 1;
 	}
 
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index ef77b15..bab08b0 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -368,8 +368,9 @@ static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int timer1, timer2;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 
-	pcl711_set_changain(dev, cmd->chanlist[0]);
+	pcl711_set_changain(dev, chanlist[0]);
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		/*
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index d196343..89cf445 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -658,6 +658,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	const struct pcl812_board *board = comedi_board(dev);
 	unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 
 	if (cmd->start_src != TRIG_NOW)
 		return -EINVAL;
@@ -689,7 +690,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
 
 	devpriv->ai_n_chan = cmd->chanlist_len;
-	memcpy(devpriv->ai_chanlist, cmd->chanlist,
+	memcpy(devpriv->ai_chanlist, chanlist,
 	       sizeof(unsigned int) * cmd->scan_end_arg);
 	/*  select first channel and range */
 	setup_range_channel(dev, s, devpriv->ai_chanlist[0], 1);
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index f65fd66..59838ab 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -451,6 +451,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	const struct pcl816_board *board = comedi_board(dev);
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp, divisor1 = 0, divisor2 = 0;
 
@@ -566,8 +567,8 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
 
 	/* step 5: complain about special chanlist considerations */
 
-	if (cmd->chanlist) {
-		if (!check_channel_list(dev, s, cmd->chanlist,
+	if (chanlist) {
+		if (!check_channel_list(dev, s, chanlist,
 					cmd->chanlist_len))
 			return 5;	/*  incorrect channels list */
 	}
@@ -580,6 +581,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	const struct pcl816_board *board = comedi_board(dev);
 	unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int seglen;
 
 	if (cmd->start_src != TRIG_NOW)
@@ -615,10 +617,10 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
 
-	seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
+	seglen = check_channel_list(dev, s, chanlist, cmd->chanlist_len);
 	if (seglen < 1)
 		return -EINVAL;
-	setup_channel_list(dev, s, cmd->chanlist, seglen);
+	setup_channel_list(dev, s, chanlist, seglen);
 	udelay(1);
 
 	devpriv->ai_n_chan = cmd->chanlist_len;
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 023a27d..72fff46 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -1258,6 +1258,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		      struct comedi_cmd *cmd)
 {
 	const struct pcl818_board *board = comedi_board(dev);
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int err = 0;
 	int tmp, divisor1 = 0, divisor2 = 0;
 
@@ -1363,8 +1364,8 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 
 	/* step 5: complain about special chanlist considerations */
 
-	if (cmd->chanlist) {
-		if (!check_channel_list(dev, s, cmd->chanlist,
+	if (chanlist) {
+		if (!check_channel_list(dev, s, chanlist,
 					cmd->chanlist_len))
 			return 5;	/*  incorrect channels list */
 	}
@@ -1378,11 +1379,12 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int retval;
 
 	dev_dbg(dev->class_dev, "pcl818_ai_cmd()\n");
 	devpriv->ai_n_chan = cmd->chanlist_len;
-	devpriv->ai_chanlist = cmd->chanlist;
+	devpriv->ai_chanlist = chanlist;
 	devpriv->ai_flags = cmd->flags;
 	devpriv->ai_data_len = s->async->prealloc_bufsz;
 	devpriv->ai_data = s->async->prealloc_buf;
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index a10bf0a..95ce9f0 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -524,8 +524,12 @@ static void pcmmio_stop_intr(struct comedi_device *dev,
 
 static irqreturn_t interrupt_pcmmio(int irq, void *d)
 {
-	int asic, got1 = 0;
 	struct comedi_device *dev = (struct comedi_device *)d;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+	unsigned int *chanlist;
+	int asic, got1 = 0;
 	int i;
 
 	for (asic = 0; asic < MAX_ASICS; ++asic) {
@@ -576,7 +580,6 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 					       flags);
 
 			if (triggered) {
-				struct comedi_subdevice *s;
 				/*
 				 * TODO here: dispatch io lines to subdevs
 				 * with commands..
@@ -586,6 +589,10 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 				     irq, asic, triggered);
 				for (i = 2; i < dev->n_subdevices; i++) {
 					s = &dev->subdevices[i];
+					async = s->async;
+					cmd = &async->cmd;
+					chanlist = cmd->chanlist.kernel_data;
+
 					/*
 					 * this is an interrupt subdev,
 					 * and it matches this asic!
@@ -598,7 +605,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 								  intr.spinlock,
 								  flags);
 
-						oldevents = s->async->events;
+						oldevents = async->events;
 
 						if (subpriv->dio.intr.active) {
 							unsigned mytrig =
@@ -618,24 +625,20 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 								unsigned int n,
 								    ch, len;
 
-								len =
-								    s->
-								    async->cmd.chanlist_len;
+								len = cmd->chanlist_len;
 								for (n = 0;
 								     n < len;
 								     n++) {
-									ch = CR_CHAN(s->async->cmd.chanlist[n]);
+									ch = CR_CHAN(chanlist[n]);
 									if (mytrig & (1U << ch))
 										val |= (1U << n);
 								}
 								/* Write the scan to the buffer. */
-								if (comedi_buf_put(s->async, ((short *)&val)[0])
-								    &&
-								    comedi_buf_put
-								    (s->async,
-								     ((short *)
-								      &val)[1])) {
-									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+								if (comedi_buf_put(async,
+									((short *)&val)[0]) &&
+								    comedi_buf_put(async,
+									((short *) &val)[1])) {
+									async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
 								} else {
 									/* Overflow! Stop acquisition!! */
 									/* TODO: STOP_ACQUISITION_CALL_HERE!! */
@@ -650,7 +653,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 									if (subpriv->dio.intr.stop_count > 0) {
 										subpriv->dio.intr.stop_count--;
 										if (subpriv->dio.intr.stop_count == 0) {
-											s->async->events |= COMEDI_CB_EOA;
+											async->events |= COMEDI_CB_EOA;
 											/* TODO: STOP_ACQUISITION_CALL_HERE!! */
 											pcmmio_stop_intr
 											    (dev,
@@ -665,8 +668,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 						    (&subpriv->dio.intr.
 						     spinlock, flags);
 
-						if (oldevents !=
-						    s->async->events) {
+						if (oldevents != async->events) {
 							comedi_event(dev, s);
 						}
 
@@ -694,6 +696,7 @@ static int pcmmio_start_intr(struct comedi_device *dev,
 		unsigned bits = 0, pol_bits = 0, n;
 		int nports, firstport, asic, port;
 		struct comedi_cmd *cmd = &s->async->cmd;
+		unsigned int *chanlist = cmd->chanlist.kernel_data;
 
 		asic = subpriv->dio.intr.asic;
 		if (asic < 0)
@@ -703,13 +706,12 @@ static int pcmmio_start_intr(struct comedi_device *dev,
 		subpriv->dio.intr.active = 1;
 		nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
 		firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
-		if (cmd->chanlist) {
+		if (chanlist) {
 			for (n = 0; n < cmd->chanlist_len; n++) {
-				bits |= (1U << CR_CHAN(cmd->chanlist[n]));
-				pol_bits |= (CR_AREF(cmd->chanlist[n])
-					     || CR_RANGE(cmd->
-							 chanlist[n]) ? 1U : 0U)
-				    << CR_CHAN(cmd->chanlist[n]);
+				bits |= (1U << CR_CHAN(chanlist[n]));
+				pol_bits |= (CR_AREF(chanlist[n]) ||
+					     CR_RANGE(chanlist[n]) ? 1U : 0U)
+						<< CR_CHAN(chanlist[n]);
 			}
 		}
 		bits &= ((0x1 << subpriv->dio.intr.num_asic_chans) -
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 0e32119..fa43333 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -454,8 +454,12 @@ static void pcmuio_stop_intr(struct comedi_device *dev,
 
 static irqreturn_t interrupt_pcmuio(int irq, void *d)
 {
-	int asic, got1 = 0;
 	struct comedi_device *dev = (struct comedi_device *)d;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+	unsigned int *chanlist;
+	int asic, got1 = 0;
 	int i;
 
 	for (asic = 0; asic < MAX_ASICS; ++asic) {
@@ -503,13 +507,16 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 					       flags);
 
 			if (triggered) {
-				struct comedi_subdevice *s;
 				/* TODO here: dispatch io lines to subdevs with commands.. */
 				printk
 				    ("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n",
 				     irq, asic, triggered);
 				for (i = 0; i < dev->n_subdevices; i++) {
 					s = &dev->subdevices[i];
+					async = s->async;
+					cmd = &async->cmd;
+					chanlist = cmd->chanlist.kernel_data;
+
 					if (subpriv->intr.asic == asic) {	/* this is an interrupt subdev, and it matches this asic! */
 						unsigned long flags;
 						unsigned oldevents;
@@ -518,7 +525,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 								  intr.spinlock,
 								  flags);
 
-						oldevents = s->async->events;
+						oldevents = async->events;
 
 						if (subpriv->intr.active) {
 							unsigned mytrig =
@@ -538,26 +545,22 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 								unsigned int n,
 								    ch, len;
 
-								len =
-								    s->
-								    async->cmd.chanlist_len;
+								len = cmd->chanlist_len;
 								for (n = 0;
 								     n < len;
 								     n++) {
-									ch = CR_CHAN(s->async->cmd.chanlist[n]);
+									ch = CR_CHAN(chanlist[n]);
 									if (mytrig & (1U << ch)) {
 										val |= (1U << n);
 									}
 								}
 								/* Write the scan to the buffer. */
-								if (comedi_buf_put(s->async, ((short *)&val)[0])
-								    &&
-								    comedi_buf_put
-								    (s->async,
-								     ((short *)
-								      &val)[1]))
+								if (comedi_buf_put(async,
+									((short *)&val)[0]) &&
+								    comedi_buf_put(async,
+									((short *)&val)[1]))
 								{
-									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+									async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
 								} else {
 									/* Overflow! Stop acquisition!! */
 									/* TODO: STOP_ACQUISITION_CALL_HERE!! */
@@ -572,7 +575,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 									if (subpriv->intr.stop_count > 0) {
 										subpriv->intr.stop_count--;
 										if (subpriv->intr.stop_count == 0) {
-											s->async->events |= COMEDI_CB_EOA;
+											async->events |= COMEDI_CB_EOA;
 											/* TODO: STOP_ACQUISITION_CALL_HERE!! */
 											pcmuio_stop_intr
 											    (dev,
@@ -587,8 +590,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 						    (&subpriv->intr.spinlock,
 						     flags);
 
-						if (oldevents !=
-						    s->async->events) {
+						if (oldevents != async->events) {
 							comedi_event(dev, s);
 						}
 
@@ -616,6 +618,7 @@ static int pcmuio_start_intr(struct comedi_device *dev,
 		unsigned bits = 0, pol_bits = 0, n;
 		int nports, firstport, asic, port;
 		struct comedi_cmd *cmd = &s->async->cmd;
+		unsigned int *chanlist = cmd->chanlist.kernel_data;
 
 		asic = subpriv->intr.asic;
 		if (asic < 0)
@@ -625,13 +628,12 @@ static int pcmuio_start_intr(struct comedi_device *dev,
 		subpriv->intr.active = 1;
 		nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
 		firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
-		if (cmd->chanlist) {
+		if (chanlist) {
 			for (n = 0; n < cmd->chanlist_len; n++) {
-				bits |= (1U << CR_CHAN(cmd->chanlist[n]));
-				pol_bits |= (CR_AREF(cmd->chanlist[n])
-					     || CR_RANGE(cmd->
-							 chanlist[n]) ? 1U : 0U)
-				    << CR_CHAN(cmd->chanlist[n]);
+				bits |= (1U << CR_CHAN(chanlist[n]));
+				pol_bits |= (CR_AREF(chanlist[n]) ||
+					     CR_RANGE(chanlist[n]) ? 1U : 0U)
+					     << CR_CHAN(chanlist[n]);
 			}
 		}
 		bits &= ((0x1 << subpriv->intr.num_asic_chans) -
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index e95a4eb..7ea468a 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -582,6 +582,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct local_info_t *local = (struct local_info_t *)s->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int counter;
 	int scanlist_start_on_every_entry;
 	int threshold;
@@ -634,7 +635,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	for (i = 0; i < cmd->chanlist_len; i++) {
 
-		int chanspec = cmd->chanlist[i];
+		int chanspec = chanlist[i];
 
 		/* Program one scan list entry */
 
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 58f5922..a4152a8 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -1175,6 +1175,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct rtdPrivate *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int timer;
 
 	/* stop anything currently running */
@@ -1209,7 +1210,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	/* start configuration */
 	/* load channel list and reset CGT */
-	rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+	rtd_load_channelgain_list(dev, cmd->chanlist_len, chanlist);
 
 	/* setup the common case and override if needed */
 	if (cmd->chanlist_len > 1) {
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index f90578e..ca93678 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -1327,14 +1327,14 @@ static int s626_ai_insn_read(struct comedi_device *dev,
 
 static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
 {
-
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	int n;
 
 	for (n = 0; n < cmd->chanlist_len; n++) {
-		if (CR_RANGE((cmd->chanlist)[n]) == 0)
-			ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V);
+		if (CR_RANGE((chanlist)[n]) == 0)
+			ppl[n] = CR_CHAN(chanlist[n]) | RANGE_5V;
 		else
-			ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V);
+			ppl[n] = CR_CHAN(chanlist[n]) | RANGE_10V;
 	}
 	if (n != 0)
 		ppl[n - 1] |= EOPL;
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 7aac213..e0a96e1 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -394,17 +394,13 @@ static int usbdux_ai_cancel(struct comedi_device *dev,
 /* analogue IN - interrupt service routine */
 static void usbduxsub_ai_IsocIrq(struct urb *urb)
 {
-	int i, err, n;
-	struct usbduxsub *this_usbduxsub;
-	struct comedi_device *this_comedidev;
-	struct comedi_subdevice *s;
-
-	/* the context variable points to the subdevice */
-	this_comedidev = urb->context;
-	/* the private structure of the subdevice is struct usbduxsub */
-	this_usbduxsub = this_comedidev->private;
-	/* subdevice which is the AD converter */
-	s = &this_comedidev->subdevices[SUBDEV_AD];
+	struct comedi_device *this_comedidev = urb->context;
+	struct usbduxsub *this_usbduxsub = this_comedidev->private;
+	struct comedi_subdevice *s = &this_comedidev->subdevices[SUBDEV_AD];
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
+	int i, err;
 
 	/* first we test if something unusual has just happened */
 	switch (urb->status) {
@@ -431,8 +427,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 		if (this_usbduxsub->ai_cmd_running) {
 			/* we are still running a command */
 			/* tell this comedi */
-			s->async->events |= COMEDI_CB_EOA;
-			s->async->events |= COMEDI_CB_ERROR;
+			async->events |= COMEDI_CB_EOA;
+			async->events |= COMEDI_CB_ERROR;
 			comedi_event(this_usbduxsub->comedidev, s);
 			/* stop the transfer w/o unlink */
 			usbdux_ai_stop(this_usbduxsub, 0);
@@ -446,8 +442,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 			dev_err(&urb->dev->dev,
 				"Non-zero urb status received in ai intr "
 				"context: %d\n", urb->status);
-			s->async->events |= COMEDI_CB_EOA;
-			s->async->events |= COMEDI_CB_ERROR;
+			async->events |= COMEDI_CB_EOA;
+			async->events |= COMEDI_CB_ERROR;
 			comedi_event(this_usbduxsub->comedidev, s);
 			/* don't do an unlink here */
 			usbdux_ai_stop(this_usbduxsub, 0);
@@ -479,8 +475,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 			dev_err(&urb->dev->dev,
 				"buggy USB host controller or bug in IRQ "
 				"handler!\n");
-		s->async->events |= COMEDI_CB_EOA;
-		s->async->events |= COMEDI_CB_ERROR;
+		async->events |= COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_event(this_usbduxsub->comedidev, s);
 		/* don't do an unlink here */
 		usbdux_ai_stop(this_usbduxsub, 0);
@@ -503,22 +499,19 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 			/* prevent a resubmit next time */
 			usbdux_ai_stop(this_usbduxsub, 0);
 			/* say comedi that the acquistion is over */
-			s->async->events |= COMEDI_CB_EOA;
+			async->events |= COMEDI_CB_EOA;
 			comedi_event(this_usbduxsub->comedidev, s);
 			return;
 		}
 	}
 	/* get the data from the USB bus and hand it over to comedi */
-	n = s->async->cmd.chanlist_len;
-	for (i = 0; i < n; i++) {
+	for (i = 0; i < cmd->chanlist_len; i++) {
 		/* transfer data */
-		if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
-			err = comedi_buf_put
-			    (s->async,
+		if (CR_RANGE(chanlist[i]) <= 1) {
+			err = comedi_buf_put(async,
 			     le16_to_cpu(this_usbduxsub->inBuffer[i]) ^ 0x800);
 		} else {
-			err = comedi_buf_put
-			    (s->async,
+			err = comedi_buf_put(async,
 			     le16_to_cpu(this_usbduxsub->inBuffer[i]));
 		}
 		if (unlikely(err == 0)) {
@@ -528,7 +521,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 		}
 	}
 	/* tell comedi that data is there */
-	s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+	async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
 	comedi_event(this_usbduxsub->comedidev, s);
 }
 
@@ -1192,10 +1185,11 @@ static int usbdux_ai_inttrig(struct comedi_device *dev,
 
 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
+	struct usbduxsub *this_usbduxsub = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int chan, range;
 	int i, ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
 	int result;
 
 	if (!this_usbduxsub)
@@ -1223,8 +1217,8 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
 	for (i = 0; i < cmd->chanlist_len; ++i) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		range = CR_RANGE(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		range = CR_RANGE(chanlist[i]);
 		if (i >= NUMCHANNELS) {
 			dev_err(&this_usbduxsub->interface->dev,
 				"comedi%d: channel list too long\n",
@@ -1626,10 +1620,11 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
 
 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
+	struct usbduxsub *this_usbduxsub = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int chan, gain;
 	int i, ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
 
 	if (!this_usbduxsub)
 		return -EFAULT;
@@ -1645,8 +1640,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/* set current channel of the running acquisition to zero */
 	s->async->cur_chan = 0;
 	for (i = 0; i < cmd->chanlist_len; ++i) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		gain = CR_RANGE(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		gain = CR_RANGE(chanlist[i]);
 		if (i >= NUMOUTCHANNELS) {
 			dev_err(&this_usbduxsub->interface->dev,
 				"comedi%d: %s: channel list too long\n",
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 3f68fc3..9426061 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -745,6 +745,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 			     struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int chan, gain, rngmask = 0xff;
 	int i, j, ret;
 	struct usbduxfastsub_s *udfs;
@@ -779,9 +780,9 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 	udfs->ignore = PACKETS_TO_IGNORE;
 
 	if (cmd->chanlist_len > 0) {
-		gain = CR_RANGE(cmd->chanlist[0]);
+		gain = CR_RANGE(chanlist[0]);
 		for (i = 0; i < cmd->chanlist_len; ++i) {
-			chan = CR_CHAN(cmd->chanlist[i]);
+			chan = CR_CHAN(chanlist[i]);
 			if (chan != i) {
 				printk(KERN_ERR "comedi%d: cmd is accepting "
 				       "only consecutive channels.\n",
@@ -789,7 +790,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 				up(&udfs->sem);
 				return -EINVAL;
 			}
-			if ((gain != CR_RANGE(cmd->chanlist[i]))
+			if ((gain != CR_RANGE(chanlist[i]))
 			    && (cmd->chanlist_len > 3)) {
 				printk(KERN_ERR "comedi%d: the gain must be"
 				       " the same for all channels.\n",
@@ -845,7 +846,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		 * one channel
 		 */
 
-		if (CR_RANGE(cmd->chanlist[0]) > 0)
+		if (CR_RANGE(chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
@@ -948,7 +949,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		 * commit data to the FIFO
 		 */
 
-		if (CR_RANGE(cmd->chanlist[0]) > 0)
+		if (CR_RANGE(chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
@@ -962,7 +963,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		/* we have 1 state with duration 1: state 0 */
 		steps_tmp = steps - 1;
 
-		if (CR_RANGE(cmd->chanlist[1]) > 0)
+		if (CR_RANGE(chanlist[1]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
@@ -992,7 +993,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		 */
 		steps_tmp = steps - 2;
 
-		if (CR_RANGE(cmd->chanlist[0]) > 0)
+		if (CR_RANGE(chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
@@ -1021,7 +1022,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		 * three channels
 		 */
 		for (j = 0; j < 1; j++) {
-			if (CR_RANGE(cmd->chanlist[j]) > 0)
+			if (CR_RANGE(chanlist[j]) > 0)
 				rngmask = 0xff - 0x04;
 			else
 				rngmask = 0xff;
@@ -1036,7 +1037,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 			udfs->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask;
 			udfs->dux_commands[LOGBASE + j * 2] = 0;
 
-			if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
+			if (CR_RANGE(chanlist[j + 1]) > 0)
 				rngmask = 0xff - 0x04;
 			else
 				rngmask = 0xff;
@@ -1062,7 +1063,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
 		udfs->dux_commands[LOGBASE + 4] = 0;
 
-		if (CR_RANGE(cmd->chanlist[0]) > 0)
+		if (CR_RANGE(chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
@@ -1081,7 +1082,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
 		udfs->dux_commands[LOGBASE + 6] = 0;
 
 	case 16:
-		if (CR_RANGE(cmd->chanlist[0]) > 0)
+		if (CR_RANGE(chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index 034f5df..6c1d1b8 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -1160,10 +1160,11 @@ static int usbdux_ai_inttrig(struct comedi_device *dev,
 
 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
+	struct usbduxsub *this_usbduxsub = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int chan;
 	int i, ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
 	int result;
 	uint8_t muxsg0 = 0;
 	uint8_t muxsg1 = 0;
@@ -1205,7 +1206,7 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	this_usbduxsub->dux_commands[4] = 0x00;
 
 	for (i = 0; i < cmd->chanlist_len; i++) {
-		chan = CR_CHAN(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
 		create_adc_command(chan, &muxsg0, &muxsg1);
 		if (i >= NUMCHANNELS) {
 			dev_err(&this_usbduxsub->interface->dev,
@@ -1691,6 +1692,7 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int *chanlist = cmd->chanlist.kernel_data;
 	unsigned int chan, gain;
 	int i, ret;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1709,8 +1711,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/* set current channel of the running acquisition to zero */
 	s->async->cur_chan = 0;
 	for (i = 0; i < cmd->chanlist_len; ++i) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		gain = CR_RANGE(cmd->chanlist[i]);
+		chan = CR_CHAN(chanlist[i]);
+		gain = CR_RANGE(chanlist[i]);
 		if (i >= NUMOUTCHANNELS) {
 			dev_err(&this_usbduxsub->interface->dev,
 				"comedi%d: %s: channel list too long\n",
-- 
1.7.11

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux