Module: xenomai-head
Branch: master
Commit: 64dda2abf9650aea4a782ab5b932b60ea72a7470
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=64dda2abf9650aea4a782ab5b932b60ea72a7470

Author: Alexis Berlemont <alexis.berlem...@gmail.com>
Date:   Thu Dec 24 09:24:32 2009 +0100

analogy: fix a bug in the user/kernel copy of the instruction's data

libanalogy allows the user application to find out the bit width of
any channel; however, the instruction structure, which is the
synchronous interface between user and kernel space, used by default
"unsigned int" typed values to send data. This issue was fixed.

---

 include/analogy/instruction.h                      |    6 +-
 ksrc/drivers/analogy/instruction.c                 |   20 +-
 ksrc/drivers/analogy/intel/8255.c                  |   24 +-
 ksrc/drivers/analogy/intel/parport.c               |   36 ++-
 .../analogy/national_instruments/mio_common.c      |  360 ++++++++++++--------
 ksrc/drivers/analogy/national_instruments/pcimio.c |    2 +
 .../analogy/national_instruments/tio_common.c      |   74 +++--
 ksrc/drivers/analogy/testing/fake.c                |   19 +-
 ksrc/drivers/analogy/testing/loop.c                |   18 +-
 9 files changed, 322 insertions(+), 237 deletions(-)

diff --git a/include/analogy/instruction.h b/include/analogy/instruction.h
index b1564d7..fb902cb 100644
--- a/include/analogy/instruction.h
+++ b/include/analogy/instruction.h
@@ -175,7 +175,7 @@ struct a4l_instruction {
                            /**< Channel descriptor */
        unsigned int data_size;
                            /**< Size of the intruction data */
-       lsampl_t *data;
+       void *data;
                    /**< Instruction data */
 };
 typedef struct a4l_instruction a4l_insn_t;
@@ -202,8 +202,8 @@ struct a4l_kernel_instruction {
        unsigned int idx_subd;
        unsigned int chan_desc;
        unsigned int data_size;
-       lsampl_t *data;
-       lsampl_t *__udata;
+       void *data;
+       void *__udata;
 };
 typedef struct a4l_kernel_instruction a4l_kinsn_t;
 
diff --git a/ksrc/drivers/analogy/instruction.c 
b/ksrc/drivers/analogy/instruction.c
index a2fb4ce..ed56367 100644
--- a/ksrc/drivers/analogy/instruction.c
+++ b/ksrc/drivers/analogy/instruction.c
@@ -38,10 +38,10 @@ int a4l_do_insn_gettime(a4l_kinsn_t * dsc)
        nanosecs_abs_t ns;
        uint32_t ns2;
 
-       uint32_t *data = (uint32_t *)dsc->data;
+       unsigned int *data = (unsigned int *)dsc->data;
 
        /* Basic checkings */
-       if (dsc->data_size != 2 * sizeof(uint32_t)) {
+       if (dsc->data_size != 2 * sizeof(unsigned int)) {
                __a4l_err("a4l_do_insn_gettime: data size should be 2\n");
                return -EINVAL;
        }
@@ -51,8 +51,8 @@ int a4l_do_insn_gettime(a4l_kinsn_t * dsc)
 
        /* Perform the conversion */
        ns2 = do_div(ns, 1000000000);
-       data[0] = (uint32_t) ns;
-       data[1] = (uint32_t) ns2 / 1000;
+       data[0] = (unsigned int) ns;
+       data[1] = (unsigned int) ns2 / 1000;
 
        return 0;
 }
@@ -60,21 +60,22 @@ int a4l_do_insn_gettime(a4l_kinsn_t * dsc)
 int a4l_do_insn_wait(a4l_kinsn_t * dsc)
 {
        unsigned int us;
+       unsigned int *data = (unsigned int *)dsc->data;
 
        /* Basic checkings */
-       if (dsc->data_size != 1) {
+       if (dsc->data_size != sizeof(unsigned int)) {
                __a4l_err("a4l_do_insn_wait: data size should be 1\n");
                return -EINVAL;
        }
 
-       if (dsc->data[0] > A4L_INSN_WAIT_MAX) {
+       if (data[0] > A4L_INSN_WAIT_MAX) {
                __a4l_err("a4l_do_insn_wait: wait duration is out of range\n");
                return -EINVAL;
        }
 
        /* As we use (a4l_)udelay, we have to convert the delay into
           microseconds */
-       us = dsc->data[0] / 1000;
+       us = data[0] / 1000;
 
        /* At least, the delay is rounded up to 1 microsecond */
        if (us == 0)
@@ -90,7 +91,8 @@ int a4l_do_insn_trig(a4l_cxt_t * cxt, a4l_kinsn_t * dsc)
 {
        a4l_subd_t *subd;
        a4l_dev_t *dev = a4l_get_dev(cxt);
-       lsampl_t trignum;
+       unsigned int trignum;
+       unsigned int *data = (unsigned int*)dsc->data;
 
        /* Basic checkings */
        if (dsc->data_size > 1) {
@@ -98,7 +100,7 @@ int a4l_do_insn_trig(a4l_cxt_t * cxt, a4l_kinsn_t * dsc)
                return -EINVAL;
        }
        
-       trignum = (dsc->data_size == 1) ? dsc->data[0] : 0;
+       trignum = (dsc->data_size == sizeof(unsigned int)) ? data[0] : 0;
        
        if (dsc->idx_subd >= dev->transfer.nb_subd) {
                __a4l_err("a4l_do_insn_trig: "
diff --git a/ksrc/drivers/analogy/intel/8255.c 
b/ksrc/drivers/analogy/intel/8255.c
index cf369bb..c43df78 100644
--- a/ksrc/drivers/analogy/intel/8255.c
+++ b/ksrc/drivers/analogy/intel/8255.c
@@ -132,28 +132,29 @@ int subd_8255_cancel(a4l_subd_t *subd)
 int subd_8255_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        subd_8255_t *subd_8255 = (subd_8255_t *)subd->priv;
+       uint32_t *data = (uint32_t *)insn->data;
 
-       if (insn->data[0]) {
+       if (data[0]) {
 
-               subd_8255->status &= ~insn->data[0];
-               subd_8255->status |= (insn->data[0] & insn->data[1]);
+               subd_8255->status &= ~data[0];
+               subd_8255->status |= (data[0] & data[1]);
 
-               if (insn->data[0] & 0xff)
+               if (data[0] & 0xff)
                        CALLBACK_FUNC(1, _8255_DATA, 
                                      subd_8255->status & 0xff, CALLBACK_ARG);
-               if (insn->data[0] & 0xff00)
+               if (data[0] & 0xff00)
                        CALLBACK_FUNC(1, _8255_DATA + 1, 
                                      (subd_8255->status >> 8) & 0xff, 
                                      CALLBACK_ARG);
-               if (insn->data[0] & 0xff0000)
+               if (data[0] & 0xff0000)
                        CALLBACK_FUNC(1, _8255_DATA + 2,
                                      (subd_8255->status >> 16) & 0xff, 
                                      CALLBACK_ARG);
        }
 
-       insn->data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
-       insn->data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 
8);
-       insn->data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 
16);
+       data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+       data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+       data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16);
 
        return 0;
 }
@@ -163,6 +164,7 @@ int subd_8255_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
        unsigned int mask;
        unsigned int bits;
        subd_8255_t *subd_8255 = (subd_8255_t *)subd->priv;
+       unsigned int *data = (unsigned int *)insn->data;
 
        mask = 1 << CR_CHAN(insn->chan_desc);
 
@@ -176,7 +178,7 @@ int subd_8255_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                bits = 0xf00000;
        }
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_DIO_INPUT:
                subd_8255->io_bits &= ~bits;
                break;
@@ -184,7 +186,7 @@ int subd_8255_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                subd_8255->io_bits |= bits;
                break;
        case A4L_INSN_CONFIG_DIO_QUERY:
-               insn->data[1] = (subd_8255->io_bits & bits) ? 
+               data[1] = (subd_8255->io_bits & bits) ? 
                        A4L_OUTPUT : A4L_INPUT;
                return 0;
                break;
diff --git a/ksrc/drivers/analogy/intel/parport.c 
b/ksrc/drivers/analogy/intel/parport.c
index aca04ce..dc0c75f 100644
--- a/ksrc/drivers/analogy/intel/parport.c
+++ b/ksrc/drivers/analogy/intel/parport.c
@@ -100,15 +100,16 @@ typedef struct parport_priv {
 static int parport_insn_a(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint8_t *data = (uint8_t *)insn->data;
 
-       if (insn->data[0]) {
-               devpriv->a_data &= ~insn->data[0];
-               devpriv->a_data |= (insn->data[0] & insn->data[1]);
+       if (data[0]) {
+               devpriv->a_data &= ~data[0];
+               devpriv->a_data |= (data[0] & data[1]);
 
                outb(devpriv->a_data, devpriv->io_base + PARPORT_A);
        }
 
-       insn->data[1] = inb(devpriv->io_base + PARPORT_A);
+       data[1] = inb(devpriv->io_base + PARPORT_A);
 
        return 0;
 }
@@ -117,11 +118,12 @@ static int parport_insn_config_a(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
        parport_spriv_t *spriv = (parport_spriv_t *)subd->priv;
+       unsigned int *data = (unsigned int *)insn->data;
 
        /* No need to check the channel descriptor; the input / output
           setting is global for all channels */
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
 
        case A4L_INSN_CONFIG_DIO_OUTPUT:
                spriv->io_bits = 0xff;
@@ -134,7 +136,7 @@ static int parport_insn_config_a(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                break;
 
        case A4L_INSN_CONFIG_DIO_QUERY:
-               insn->data[1] = (spriv->io_bits == 0xff) ? 
+               data[1] = (spriv->io_bits == 0xff) ? 
                        A4L_OUTPUT: A4L_INPUT;
                break;
 
@@ -150,12 +152,13 @@ static int parport_insn_config_a(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
 static int parport_insn_b(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint8_t *data = (uint8_t *)insn->data;
 
-       if (insn->data[0]) {
+       if (data[0]) {
                /* should writes be ignored? */
        }
 
-       insn->data[1] = (inb(devpriv->io_base + PARPORT_B) >> 3);
+       data[1] = (inb(devpriv->io_base + PARPORT_B) >> 3);
 
        return 0;
 }
@@ -163,26 +166,29 @@ static int parport_insn_b(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
 static int parport_insn_c(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint8_t *data = (uint8_t *)insn->data;
 
-       insn->data[0] &= 0x0f;
-       if (insn->data[0]) {
-               devpriv->c_data &= ~insn->data[0];
-               devpriv->c_data |= (insn->data[0] & insn->data[1]);
+       data[0] &= 0x0f;
+       if (data[0]) {
+               devpriv->c_data &= ~data[0];
+               devpriv->c_data |= (data[0] & data[1]);
 
                outb(devpriv->c_data, devpriv->io_base + PARPORT_C);
        }
 
-       insn->data[1] = devpriv->c_data & 0xf;
+       data[1] = devpriv->c_data & 0xf;
 
        return 2;
 }
 
 static int parport_intr_insn(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
-       if (insn->data_size < 1)
+       uint8_t *data = (uint8_t *)insn->data;
+
+       if (insn->data_size < sizeof(uint8_t))
                return -EINVAL;
 
-       insn->data[1] = 0;
+       data[1] = 0;
        return 0;
 }
 
diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c 
b/ksrc/drivers/analogy/national_instruments/mio_common.c
index ebab716..532d6db 100644
--- a/ksrc/drivers/analogy/national_instruments/mio_common.c
+++ b/ksrc/drivers/analogy/national_instruments/mio_common.c
@@ -1512,6 +1512,7 @@ static int ni_ai_insn_read(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
        unsigned int signbits;
        unsigned short d;
        unsigned long dl;
+       uint16_t *data = (uint16_t *)insn->data;
 
        ni_load_channelgain_list(dev, 1, &insn->chan_desc);
 
@@ -1524,7 +1525,7 @@ static int ni_ai_insn_read(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                                            AI_Command_1_Register);
                        a4l_udelay(1);
                }
-               for (n = 0; n < insn->data_size / sizeof(sampl_t); n++) {
+               for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) {
                        devpriv->stc_writew(dev, AI_CONVERT_Pulse,
                                            AI_Command_1_Register);
                        /* The 611x has screwy 32-bit FIFOs. */
@@ -1550,10 +1551,10 @@ static int ni_ai_insn_read(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                                return -ETIME;
                        }
                        d += signbits;
-                       insn->data[n] = d;
+                       data[n] = d;
                }
        } else if (boardtype.reg_type == ni_reg_6143) {
-               for (n = 0; n < insn->data_size / sizeof(sampl_t); n++) {
+               for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) {
                        devpriv->stc_writew(dev, AI_CONVERT_Pulse,
                                            AI_Command_1_Register);
 
@@ -1574,10 +1575,10 @@ static int ni_ai_insn_read(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                                         "timeout in 6143 ni_ai_insn_read\n");
                                return -ETIME;
                        }
-                       insn->data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 
0xFFFF;
+                       data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
                }
        } else {
-               for (n = 0; n < insn->data_size / sizeof(sampl_t); n++) {
+               for (n = 0; n < insn->data_size / sizeof(uint16_t); n++) {
                        devpriv->stc_writew(dev, AI_CONVERT_Pulse,
                                            AI_Command_1_Register);
                        for (i = 0; i < NI_TIMEOUT; i++) {
@@ -1593,13 +1594,12 @@ static int ni_ai_insn_read(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                                return -ETIME;
                        }
                        if (boardtype.reg_type & ni_reg_m_series_mask) {
-                               insn->data[n] = 
-                                       ni_readl(M_Offset_AI_FIFO_Data) & mask;
+                               data[n] = ni_readl(M_Offset_AI_FIFO_Data) & 
mask;
                        } else {
                                d = ni_readw(ADC_FIFO_Data_Register);
                                /* subtle: needs to be short addition */
                                d += signbits;  
-                               insn->data[n] = d;
+                               data[n] = d;
                        }
                }
        }
@@ -2392,6 +2392,7 @@ int ni_ai_config_analog_trig(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
        a4l_dev_t *dev = subd->dev;
        unsigned int a, b, modebits;
        int err = 0;
+       uint32_t *data = (uint32_t *)insn->data;
 
        /* data[1] is flags
         * data[2] is analog line
@@ -2400,20 +2401,20 @@ int ni_ai_config_analog_trig(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
        if (!boardtype.has_analog_trig)
                return -EINVAL;
 
-       if ((insn->data[1] & 0xffff0000) != A4L_EV_SCAN_BEGIN) {
-               insn->data[1] &= (A4L_EV_SCAN_BEGIN | 0xffff);
+       if ((data[1] & 0xffff0000) != A4L_EV_SCAN_BEGIN) {
+               data[1] &= (A4L_EV_SCAN_BEGIN | 0xffff);
                err++;
        }
-       if (insn->data[2] >= boardtype.n_adchan) {
-               insn->data[2] = boardtype.n_adchan - 1;
+       if (data[2] >= boardtype.n_adchan) {
+               data[2] = boardtype.n_adchan - 1;
                err++;
        }
-       if (insn->data[3] > 255) {      /* a */
-               insn->data[3] = 255;
+       if (data[3] > 255) {    /* a */
+               data[3] = 255;
                err++;
        }
-       if (insn->data[4] > 255) {      /* b */
-               insn->data[4] = 255;
+       if (data[4] > 255) {    /* b */
+               data[4] = 255;
                err++;
        }
        /*
@@ -2431,17 +2432,17 @@ int ni_ai_config_analog_trig(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
         *     middle mode              10 01 01 10
         */
 
-       a = insn->data[3];
-       b = insn->data[4];
-       modebits = insn->data[1] & 0xff;
+       a = data[3];
+       b = data[4];
+       modebits = data[1] & 0xff;
        if (modebits & 0xf0) {
                /* two level mode */
                if (b < a) {
                        /* swap order */
-                       a = insn->data[4];
-                       b = insn->data[3];
-                       modebits = ((insn->data[1] & 0xf) << 4) | 
-                               ((insn->data[1] & 0xf0) >> 4);
+                       a = data[4];
+                       b = data[3];
+                       modebits = ((data[1] & 0xf) << 4) | 
+                               ((data[1] & 0xf0) >> 4);
                }
                devpriv->atrig_low = a;
                devpriv->atrig_high = b;
@@ -2456,13 +2457,13 @@ int ni_ai_config_analog_trig(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                        devpriv->atrig_mode = 2;
                        break;
                default:
-                       insn->data[1] &= ~0xff;
+                       data[1] &= ~0xff;
                        err++;
                }
        } else {
                /* one level mode */
                if (b != 0) {
-                       insn->data[4] = 0;
+                       data[4] = 0;
                        err++;
                }
                switch (modebits) {
@@ -2475,7 +2476,7 @@ int ni_ai_config_analog_trig(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                        devpriv->atrig_mode = 1;
                        break;
                default:
-                       insn->data[1] &= ~0xff;
+                       data[1] &= ~0xff;
                        err++;
                }
        }
@@ -2489,26 +2490,27 @@ int ni_ai_config_analog_trig(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
 int ni_ai_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       unsigned int *data = (unsigned int *)insn->data;
 
-       if (insn->data_size < 1)
+       if (insn->data_size < sizeof(unsigned int))
                return -EINVAL;
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_ANALOG_TRIG:
                return ni_ai_config_analog_trig(subd, insn);
        case A4L_INSN_CONFIG_ALT_SOURCE:
                if (boardtype.reg_type & ni_reg_m_series_mask) {
-                       if (insn->data[1] & 
~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
-                                             
MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
-                                             MSeries_AI_Bypass_Mode_Mux_Mask |
-                                             
MSeries_AO_Bypass_AO_Cal_Sel_Mask)) {
+                       if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+                                       MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+                                       MSeries_AI_Bypass_Mode_Mux_Mask |
+                                       MSeries_AO_Bypass_AO_Cal_Sel_Mask)) {
                                return -EINVAL;
                        }
-                       devpriv->ai_calib_source = insn->data[1];
+                       devpriv->ai_calib_source = data[1];
                } else if (boardtype.reg_type == ni_reg_6143) {
                        unsigned int calib_source;
 
-                       calib_source = insn->data[1] & 0xf;
+                       calib_source = data[1] & 0xf;
 
                        if (calib_source > 0xF)
                                return -EINVAL;
@@ -2519,8 +2521,8 @@ int ni_ai_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
                        unsigned int calib_source;
                        unsigned int calib_source_adjust;
 
-                       calib_source = insn->data[1] & 0xf;
-                       calib_source_adjust = (insn->data[1] >> 4) & 0xff;
+                       calib_source = data[1] & 0xf;
+                       calib_source_adjust = (data[1] >> 4) & 0xff;
 
                        if (calib_source >= 8)
                                return -EINVAL;
@@ -2544,11 +2546,11 @@ static void ni_ao_munge(a4l_subd_t *subd, void *buf, 
unsigned long size)
        a4l_dev_t *dev = subd->dev;
        a4l_cmd_t *cmd = a4l_get_cmd(subd);
        int chan_idx = a4l_get_chan(subd);
-       sampl_t *array = buf;
+       uint16_t *array = buf;
        unsigned int i, range, offset;
 
        offset = 1 << (boardtype.aobits - 1);
-       for (i = 0; i < size / sizeof(sampl_t); i++) {
+       for (i = 0; i < size / sizeof(uint16_t); i++) {
 
                range = CR_RNG(cmd->chan_descs[chan_idx]);
                if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
@@ -2700,8 +2702,9 @@ static int ni_ao_config_chan_descs(a4l_subd_t *subd,
 int ni_ao_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint16_t *data = (uint16_t *)insn->data;
 
-       insn->data[0] = devpriv->ao[CR_CHAN(insn->chan_desc)];
+       data[0] = devpriv->ao[CR_CHAN(insn->chan_desc)];
 
        return 0;
 }
@@ -2710,17 +2713,18 @@ int ni_ao_insn_write(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
 {
        a4l_dev_t *dev = subd->dev;
        unsigned int chan = CR_CHAN(insn->chan_desc);
+       uint16_t *data = (uint16_t *)insn->data;
        unsigned int invert;
 
        invert = ni_ao_config_chan_descs(subd, 
                                         &insn->chan_desc, 1, 0);
 
-       devpriv->ao[chan] = insn->data[0];
+       devpriv->ao[chan] = data[0];
 
        if (boardtype.reg_type & ni_reg_m_series_mask) {
-               ni_writew(insn->data[0], M_Offset_DAC_Direct_Data(chan));
+               ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
        } else
-               ni_writew(insn->data[0] ^ invert,
+               ni_writew(data[0] ^ invert,
                          (chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
 
        return 0;
@@ -2730,6 +2734,7 @@ int ni_ao_insn_write_671x(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
 {
        a4l_dev_t *dev = subd->dev;
        unsigned int chan = CR_CHAN(insn->chan_desc);
+       uint16_t *data = (uint16_t *)insn->data;
        unsigned int invert;
 
        ao_win_out(1 << chan, AO_Immediate_671x);
@@ -2737,8 +2742,8 @@ int ni_ao_insn_write_671x(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
 
        ni_ao_config_chan_descs(subd, &insn->chan_desc, 1, 0);
 
-       devpriv->ao[chan] = insn->data[0];
-       ao_win_out(insn->data[0] ^ invert, DACx_Direct_Data_671x(chan));
+       devpriv->ao[chan] = data[0];
+       ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
 
        return 0;
 }
@@ -3115,14 +3120,15 @@ int ni_ao_reset(a4l_subd_t *subd)
 int ni_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       unsigned int *data = (unsigned int *)insn->data;
 
 #ifdef CONFIG_DEBUG_DIO
        a4l_info(dev,
                 "ni_dio_insn_config() chan=%d io=%d\n",
-                CR_CHAN(insn->chan_desc), insn->data[0]);
+                CR_CHAN(insn->chan_desc), data[0]);
 #endif /* CONFIG_DEBUG_DIO */
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_DIO_OUTPUT:
                devpriv->io_bits |= 1 << CR_CHAN(insn->chan_desc);
                break;
@@ -3130,10 +3136,9 @@ int ni_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                devpriv->io_bits &= ~(1 << CR_CHAN(insn->chan_desc));
                break;
        case A4L_INSN_CONFIG_DIO_QUERY:
-               insn->data[1] =
-                       (devpriv->io_bits & (1 << CR_CHAN(insn->
-                                                         chan_desc))) ? 
A4L_OUTPUT :
-               A4L_INPUT;
+               data[1] = (devpriv->io_bits & 
+                          (1 << CR_CHAN(insn->chan_desc))) ? 
+                       A4L_OUTPUT : A4L_INPUT;
                return 0;
                break;
        default:
@@ -3150,43 +3155,50 @@ int ni_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
 int ni_dio_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint8_t *data = (uint8_t *)insn->data;
 
 #ifdef CONFIG_DEBUG_DIO
        a4l_info(dev, 
-                "ni_dio_insn_bits() mask=0x%x bits=0x%x\n", 
-                insn->data[0], insn->data[1]);
+                "ni_dio_insn_bits_8() mask=0x%x bits=0x%x\n", 
+                data[0], data[1]);
 #endif
-       if (insn->data_size != 2 * sizeof(lsampl_t))
+
+       if (insn->data_size != 2 * sizeof(uint8_t))
                return -EINVAL;
-       if (insn->data[0]) {
+
+       if (data[0]) {
                /* Perform check to make sure we're not using the
                   serial part of the dio */
-               if ((insn->data[0] & (DIO_SDIN | DIO_SDOUT))
+               if ((data[0] & (DIO_SDIN | DIO_SDOUT))
                    && devpriv->serial_interval_ns)
                        return -EBUSY;
 
-               devpriv->dio_state &= ~insn->data[0];
-               devpriv->dio_state |= (insn->data[0] & insn->data[1]);
+               devpriv->dio_state &= ~data[0];
+               devpriv->dio_state |= (data[0] & data[1]);
                devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
-               devpriv->dio_output |= 
DIO_Parallel_Data_Out(devpriv->dio_state);
+               devpriv->dio_output |= 
+                       DIO_Parallel_Data_Out(devpriv->dio_state);
                devpriv->stc_writew(dev, devpriv->dio_output,
                                    DIO_Output_Register);
        }
-       insn->data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
 
+       data[1] = (uint8_t) 
+               devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
+       
        return 0;
 }
 
 int ni_m_series_dio_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       unsigned int *data = (unsigned int *)insn->data;
 
 #ifdef CONFIG_DEBUG_DIO
        a4l_info(dev, 
                 "ni_m_series_dio_insn_config() chan=%d io=%d\n",
-                CR_CHAN(insn->chan_desc), insn->data[0]);
+                CR_CHAN(insn->chan_desc), data[0]);
 #endif
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_DIO_OUTPUT:
                devpriv->io_bits |= 1 << CR_CHAN(insn->chan_desc);
                break;
@@ -3194,9 +3206,8 @@ int ni_m_series_dio_insn_config(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                devpriv->io_bits &= ~(1 << CR_CHAN(insn->chan_desc));
                break;
        case A4L_INSN_CONFIG_DIO_QUERY:
-               insn->data[1] =
-                       (devpriv->io_bits & 
-                        (1 << CR_CHAN(insn->chan_desc))) ? 
+               data[1] = (devpriv->io_bits & 
+                          (1 << CR_CHAN(insn->chan_desc))) ? 
                        A4L_OUTPUT : A4L_INPUT;
                return 0;
                break;
@@ -3209,28 +3220,57 @@ int ni_m_series_dio_insn_config(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
        return 0;
 }
 
-int ni_m_series_dio_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn)
+int ni_m_series_dio_insn_bits_8(a4l_subd_t *subd, a4l_kinsn_t *insn)
+{
+       a4l_dev_t *dev = subd->dev;
+       uint8_t *data = (uint8_t *)insn->data;
+
+#ifdef CONFIG_DEBUG_DIO
+       a4l_info(dev, 
+                "ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", 
+                data[0], data[1]);
+#endif
+
+       if (insn->data_size != 2 * sizeof(uint8_t))
+               return -EINVAL;
+
+       if (data[0]) {
+               devpriv->dio_state &= ~data[0];
+               devpriv->dio_state |= (data[0] & data[1]);
+               ni_writel(devpriv->dio_state, M_Offset_Static_Digital_Output);
+       }
+
+       data[1] = (uint8_t) ni_readl(M_Offset_Static_Digital_Input);
+
+       return 0;
+}
+
+int ni_m_series_dio_insn_bits_32(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint32_t *data = (uint32_t *)insn->data;
 
 #ifdef CONFIG_DEBUG_DIO
        a4l_info(dev, 
                 "ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", 
-                insn->data[0], insn->data[1]);
+                data[0], data[1]);
 #endif
 
-       if (insn->data_size != 2 * sizeof(lsampl_t))
+       if (insn->data_size != 2 * sizeof(uint32_t))
                return -EINVAL;
-       if (insn->data[0]) {
-               devpriv->dio_state &= ~insn->data[0];
-               devpriv->dio_state |= (insn->data[0] & insn->data[1]);
+
+       if (data[0]) {
+               devpriv->dio_state &= ~data[0];
+               devpriv->dio_state |= (data[0] & data[1]);
                ni_writel(devpriv->dio_state, M_Offset_Static_Digital_Output);
        }
-       insn->data[1] = ni_readl(M_Offset_Static_Digital_Input);
+
+       data[1] = ni_readl(M_Offset_Static_Digital_Input);
 
        return 0;
 }
 
+
 a4l_cmd_t mio_dio_cmd_mask = {
        .idx_subd = 0,
        .start_src = TRIG_INT,
@@ -3527,11 +3567,12 @@ int ni_serial_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
        a4l_dev_t *dev = subd->dev;
        int err = 0;
        unsigned char byte_out, byte_in = 0;
+       unsigned int *data = (unsigned int *)insn->data;
 
-       if (insn->data_size != 2 * sizeof(lsampl_t))
+       if (insn->data_size != 2 * sizeof(unsigned int))
                return -EINVAL;
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_SERIAL_CLOCK:
 
 #ifdef CONFIG_DEBUG_DIO
@@ -3541,27 +3582,27 @@ int ni_serial_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                devpriv->serial_hw_mode = 1;
                devpriv->dio_control |= DIO_HW_Serial_Enable;
 
-               if (insn->data[1] == SERIAL_DISABLED) {
+               if (data[1] == SERIAL_DISABLED) {
                        devpriv->serial_hw_mode = 0;
                        devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
                                                  DIO_Software_Serial_Control);
-                       insn->data[1] = SERIAL_DISABLED;
-                       devpriv->serial_interval_ns = insn->data[1];
-               } else if (insn->data[1] <= SERIAL_600NS) {
+                       data[1] = SERIAL_DISABLED;
+                       devpriv->serial_interval_ns = data[1];
+               } else if (data[1] <= SERIAL_600NS) {
                        /* Warning: this clock speed is too fast to reliably
                           control SCXI. */
                        devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
                        devpriv->clock_and_fout |= Slow_Internal_Timebase;
                        devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
-                       insn->data[1] = SERIAL_600NS;
-                       devpriv->serial_interval_ns = insn->data[1];
-               } else if (insn->data[1] <= SERIAL_1_2US) {
+                       data[1] = SERIAL_600NS;
+                       devpriv->serial_interval_ns = data[1];
+               } else if (data[1] <= SERIAL_1_2US) {
                        devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
                        devpriv->clock_and_fout |= Slow_Internal_Timebase |
                                DIO_Serial_Out_Divide_By_2;
-                       insn->data[1] = SERIAL_1_2US;
-                       devpriv->serial_interval_ns = insn->data[1];
-               } else if (insn->data[1] <= SERIAL_10US) {
+                       data[1] = SERIAL_1_2US;
+                       devpriv->serial_interval_ns = data[1];
+               } else if (data[1] <= SERIAL_10US) {
                        devpriv->dio_control |= DIO_HW_Serial_Timebase;
                        devpriv->clock_and_fout |= Slow_Internal_Timebase |
                                DIO_Serial_Out_Divide_By_2;
@@ -3569,14 +3610,14 @@ int ni_serial_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                           600ns/1.2us. If you turn divide_by_2 off with the
                           slow clock, you will still get 10us, except then
                           all your delays are wrong. */
-                       insn->data[1] = SERIAL_10US;
-                       devpriv->serial_interval_ns = insn->data[1];
+                       data[1] = SERIAL_10US;
+                       devpriv->serial_interval_ns = data[1];
                } else {
                        devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
                                                  DIO_Software_Serial_Control);
                        devpriv->serial_hw_mode = 0;
-                       insn->data[1] = (insn->data[1] / 1000) * 1000;
-                       devpriv->serial_interval_ns = insn->data[1];
+                       data[1] = (data[1] / 1000) * 1000;
+                       devpriv->serial_interval_ns = data[1];
                }
 
                devpriv->stc_writew(dev, devpriv->dio_control,
@@ -3593,7 +3634,7 @@ int ni_serial_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                        return -EINVAL;
                }
 
-               byte_out = insn->data[1] & 0xFF;
+               byte_out = data[1] & 0xFF;
 
                if (devpriv->serial_hw_mode) {
                        err = ni_serial_hw_readwrite8(dev, byte_out, &byte_in);
@@ -3606,7 +3647,7 @@ int ni_serial_insn_config(a4l_subd_t *subd, a4l_kinsn_t 
*insn)
                }
                if (err < 0)
                        return err;
-               insn->data[1] = byte_in & 0xFF;
+               data[1] = byte_in & 0xFF;
                return 0;
 
                break;
@@ -3830,20 +3871,24 @@ static unsigned int ni_gpct_read_register(struct 
ni_gpct *counter,
 
 int ni_freq_out_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
-       a4l_dev_t *dev = subd->dev;
-       insn->data[0] = FOUT_Divider(devpriv->clock_and_fout);
+       a4l_dev_t *dev = subd->dev;     
+       uint8_t *data = (uint8_t *)insn->data;
+
+       data[0] = FOUT_Divider(devpriv->clock_and_fout);
+
        return 0;
 }
 
 int ni_freq_out_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       uint8_t *data = (uint8_t *)insn->data;
 
        devpriv->clock_and_fout &= ~FOUT_Enable;
        devpriv->stc_writew(dev, devpriv->clock_and_fout,
                            Clock_and_FOUT_Register);
        devpriv->clock_and_fout &= ~FOUT_Divider_mask;
-       devpriv->clock_and_fout |= FOUT_Divider(insn->data[0]);
+       devpriv->clock_and_fout |= FOUT_Divider(data[0]);
        devpriv->clock_and_fout |= FOUT_Enable;
        devpriv->stc_writew(dev, devpriv->clock_and_fout,
                            Clock_and_FOUT_Register);
@@ -3870,8 +3915,8 @@ static int ni_set_freq_out_clock(a4l_dev_t * dev, 
lsampl_t clock_source)
 }
 
 static void ni_get_freq_out_clock(a4l_dev_t * dev, 
-                                 lsampl_t * clock_source, 
-                                 lsampl_t * clock_period_ns)
+                                 unsigned int * clock_source, 
+                                 unsigned int * clock_period_ns)
 {
        if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
                *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
@@ -3885,17 +3930,19 @@ static void ni_get_freq_out_clock(a4l_dev_t * dev,
 int ni_freq_out_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       unsigned int *data = (unsigned int *)insn->data;
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_SET_CLOCK_SRC:
-               return ni_set_freq_out_clock(dev, insn->data[1]);
+               return ni_set_freq_out_clock(dev, data[1]);
                break;
        case A4L_INSN_CONFIG_GET_CLOCK_SRC:
-               ni_get_freq_out_clock(dev, &insn->data[1], &insn->data[2]);
+               ni_get_freq_out_clock(dev, &data[1], &data[2]);
                return 0;
        default:
                break;
        }
+
        return -EINVAL;
 }
 
@@ -3946,7 +3993,10 @@ static int ni_read_eeprom(a4l_dev_t *dev, int addr)
 static int ni_eeprom_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       insn->data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chan_desc));
+       uint8_t *data = (uint8_t *)insn->data;
+
+       data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chan_desc));
+
        return 0;
 }
 
@@ -3954,63 +4004,70 @@ static int ni_eeprom_insn_read(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
 static int ni_m_series_eeprom_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       insn->data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chan_desc)];
+       uint8_t *data = (uint8_t *)insn->data;
+
+       data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chan_desc)];
+
        return 0;
 }
 
 static int ni_get_pwm_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       insn->data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
-       insn->data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
+       unsigned int *data = (unsigned int*)insn->data;
+
+       data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
+       data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
+
        return 0;
 }
 
 static int ni_m_series_pwm_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       unsigned up_count, down_count;
+       unsigned int up_count, down_count;
+       unsigned int *data = (unsigned int*)insn->data;
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_PWM_OUTPUT:
-               switch (insn->data[1]) {
+               switch (data[1]) {
                case TRIG_ROUND_NEAREST:
                        up_count =
-                               (insn->data[2] +
+                               (data[2] +
                                 devpriv->clock_ns / 2) / devpriv->clock_ns;
                        break;
                case TRIG_ROUND_DOWN:
-                       up_count = insn->data[2] / devpriv->clock_ns;
+                       up_count = data[2] / devpriv->clock_ns;
                        break;
                case TRIG_ROUND_UP:
-                       up_count =(insn->data[2] + devpriv->clock_ns - 1) /
+                       up_count =(data[2] + devpriv->clock_ns - 1) /
                                devpriv->clock_ns;
                        break;
                default:
                        return -EINVAL;
                        break;
                }
-               switch (insn->data[3]) {
+               switch (data[3]) {
                case TRIG_ROUND_NEAREST:
-                       down_count = (insn->data[4] + devpriv->clock_ns / 2) /
+                       down_count = (data[4] + devpriv->clock_ns / 2) /
                                devpriv->clock_ns;
                        break;
                case TRIG_ROUND_DOWN:
-                       down_count = insn->data[4] / devpriv->clock_ns;
+                       down_count = data[4] / devpriv->clock_ns;
                        break;
                case TRIG_ROUND_UP:
                        down_count =
-                               (insn->data[4] + devpriv->clock_ns - 1) /
+                               (data[4] + devpriv->clock_ns - 1) /
                                devpriv->clock_ns;
                        break;
                default:
                        return -EINVAL;
                        break;
                }
-               if (up_count * devpriv->clock_ns != insn->data[2] ||
-                   down_count * devpriv->clock_ns != insn->data[4]) {
-                       insn->data[2] = up_count * devpriv->clock_ns;
-                       insn->data[4] = down_count * devpriv->clock_ns;
+               if (up_count * devpriv->clock_ns != data[2] ||
+                   down_count * devpriv->clock_ns != data[4]) {
+                       data[2] = up_count * devpriv->clock_ns;
+                       data[4] = down_count * devpriv->clock_ns;
                        return -EAGAIN;
                }
                ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
@@ -4033,47 +4090,48 @@ static int ni_m_series_pwm_config(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
 static int ni_6143_pwm_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
+       unsigned int *data = (unsigned int*)insn->data;
 
        unsigned up_count, down_count;
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_INSN_CONFIG_PWM_OUTPUT:
-               switch (insn->data[1]) {
+               switch (data[1]) {
                case TRIG_ROUND_NEAREST:
                        up_count =
-                               (insn->data[2] + devpriv->clock_ns / 2) /
+                               (data[2] + devpriv->clock_ns / 2) /
                                devpriv->clock_ns;
                        break;
                case TRIG_ROUND_DOWN:
-                       up_count = insn->data[2] / devpriv->clock_ns;
+                       up_count = data[2] / devpriv->clock_ns;
                        break;
                case TRIG_ROUND_UP:
-                       up_count = (insn->data[2] + devpriv->clock_ns - 1) /
+                       up_count = (data[2] + devpriv->clock_ns - 1) /
                                devpriv->clock_ns;
                        break;
                default:
                        return -EINVAL;
                        break;
                }
-               switch (insn->data[3]) {
+               switch (data[3]) {
                case TRIG_ROUND_NEAREST:
-                       down_count = (insn->data[4] + devpriv->clock_ns / 2) /
+                       down_count = (data[4] + devpriv->clock_ns / 2) /
                                devpriv->clock_ns;
                        break;
                case TRIG_ROUND_DOWN:
-                       down_count = insn->data[4] / devpriv->clock_ns;
+                       down_count = data[4] / devpriv->clock_ns;
                        break;
                case TRIG_ROUND_UP:
-                       down_count = (insn->data[4] + devpriv->clock_ns - 1) /
+                       down_count = (data[4] + devpriv->clock_ns - 1) /
                                devpriv->clock_ns;
                        break;
                default:
                        return -EINVAL;
                        break;
                }
-               if (up_count * devpriv->clock_ns != insn->data[2] ||
-                   down_count * devpriv->clock_ns != insn->data[4]) {
-                       insn->data[2] = up_count * devpriv->clock_ns;
-                       insn->data[4] = down_count * devpriv->clock_ns;
+               if (up_count * devpriv->clock_ns != data[2] ||
+                   down_count * devpriv->clock_ns != data[4]) {
+                       data[2] = up_count * devpriv->clock_ns;
+                       data[4] = down_count * devpriv->clock_ns;
                        return -EAGAIN;
                }
                ni_writel(up_count, Calibration_HighTime_6143);
@@ -4269,15 +4327,20 @@ static void caldac_setup(a4l_dev_t *dev, a4l_subd_t 
*subd)
 static int ni_calib_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       ni_write_caldac(dev, CR_CHAN(insn->chan_desc), insn->data[0]);
+       uint16_t *data = (uint16_t *)insn->data;
+
+       ni_write_caldac(dev, CR_CHAN(insn->chan_desc), data[0]);
        return 0;
 }
 
 static int ni_calib_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       insn->data[0] = devpriv->caldacs[CR_CHAN(insn->chan_desc)];
-       return 1;
+       uint16_t *data = (uint16_t *)insn->data;
+
+       data[0] = devpriv->caldacs[CR_CHAN(insn->chan_desc)];
+
+       return 0;
 }
 
 static int ni_gpct_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
@@ -4465,29 +4528,30 @@ static int ni_config_filter(a4l_dev_t *dev,
 static int ni_pfi_insn_bits(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        a4l_dev_t *dev = subd->dev;
-       if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
-               return -ENOTSUPP;
-       }
-       if (insn->data[0]) {
-               devpriv->pfi_state &= ~insn->data[0];
-               devpriv->pfi_state |= (insn->data[0] & insn->data[1]);
+       uint16_t *data = (uint16_t *)insn->data;
+
+       if (data[0]) {
+               devpriv->pfi_state &= ~data[0];
+               devpriv->pfi_state |= (data[0] & data[1]);
                ni_writew(devpriv->pfi_state, M_Offset_PFI_DO);
        }
-       insn->data[1] = ni_readw(M_Offset_PFI_DI);
+
+       data[1] = ni_readw(M_Offset_PFI_DI);
+
        return 0;
 }
 
 static int ni_pfi_insn_config(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {      
-       unsigned int chan;
        a4l_dev_t *dev = subd->dev;
+       unsigned int chan, *data = (unsigned int *)insn->data;
 
-       if (insn->data_size < 1)
+       if (insn->data_size < sizeof(unsigned int))
                return -EINVAL;
 
        chan = CR_CHAN(insn->chan_desc);
 
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case A4L_OUTPUT:
                ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1);
                break;
@@ -4495,19 +4559,18 @@ static int ni_pfi_insn_config(a4l_subd_t *subd, 
a4l_kinsn_t *insn)
                ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0);
                break;
        case A4L_INSN_CONFIG_DIO_QUERY:
-               insn->data[1] =
-                       (devpriv->io_bidirection_pin_reg & (1 << chan)) ? 
+               data[1] = (devpriv->io_bidirection_pin_reg & (1 << chan)) ? 
                        A4L_OUTPUT :    A4L_INPUT;
                return 0;
                break;
        case A4L_INSN_CONFIG_SET_ROUTING:
-               return ni_set_pfi_routing(dev, chan, insn->data[1]);
+               return ni_set_pfi_routing(dev, chan, data[1]);
                break;
        case A4L_INSN_CONFIG_GET_ROUTING:
-               insn->data[1] = ni_get_pfi_routing(dev, chan);
+               data[1] = ni_get_pfi_routing(dev, chan);
                break;
        case A4L_INSN_CONFIG_FILTER:
-               return ni_config_filter(dev, chan, insn->data[1]);
+               return ni_config_filter(dev, chan, data[1]);
                break;
        default:
                return -EINVAL;
@@ -4859,7 +4922,10 @@ int ni_E_init(a4l_dev_t *dev)
 
        if (boardtype.reg_type & ni_reg_m_series_mask) {
 
-               subd->insn_bits = ni_m_series_dio_insn_bits;
+               if (subd->chan_desc->length == 8)
+                       subd->insn_bits = ni_m_series_dio_insn_bits_8;
+               else
+                       subd->insn_bits = ni_m_series_dio_insn_bits_32;
                subd->insn_config = ni_m_series_dio_insn_config;
                subd->do_cmd = ni_cdio_cmd;
                subd->do_cmdtest = ni_cdio_cmdtest;
diff --git a/ksrc/drivers/analogy/national_instruments/pcimio.c 
b/ksrc/drivers/analogy/national_instruments/pcimio.c
index a83f4e3..eecae30 100644
--- a/ksrc/drivers/analogy/national_instruments/pcimio.c
+++ b/ksrc/drivers/analogy/national_instruments/pcimio.c
@@ -982,6 +982,7 @@ static ni_board ni_boards[]={
                .caldac = {caldac_none},
                has_8255:       0,
        },
+#if 0 /* TODO: fix data size */
        {       device_id:      0x70b6,
                name:           "pci-6280",
                n_adchan:       16,
@@ -1068,6 +1069,7 @@ static ni_board ni_boards[]={
                .caldac = {caldac_none},
                has_8255:       0,
        },
+#endif /* TODO: fix data size */
        {       device_id:      0x70C0,
                name:           "pci-6143",
                n_adchan:       8,
diff --git a/ksrc/drivers/analogy/national_instruments/tio_common.c 
b/ksrc/drivers/analogy/national_instruments/tio_common.c
index 6944201..4721fb5 100644
--- a/ksrc/drivers/analogy/national_instruments/tio_common.c
+++ b/ksrc/drivers/analogy/national_instruments/tio_common.c
@@ -831,8 +831,8 @@ static uint64_t ni_tio_clock_period_ps(const struct ni_gpct 
*counter,
 }
 
 static void ni_tio_get_clock_src(struct ni_gpct *counter,
-                                lsampl_t * clock_source, 
-                                lsampl_t * period_ns)
+                                unsigned int * clock_source, 
+                                unsigned int * period_ns)
 {
        static const unsigned int pico_per_nano = 1000;
        uint64_t temp64;
@@ -1110,7 +1110,7 @@ static int ni_tio_set_gate_src(struct ni_gpct *counter,
 }
 
 static int ni_tio_set_other_src(struct ni_gpct *counter, 
-                               unsigned int index, lsampl_t source)
+                               unsigned int index, unsigned int source)
 {
        struct ni_gpct_device *counter_dev = counter->counter_dev;
 
@@ -1307,7 +1307,8 @@ static unsigned int 
ni_m_series_second_gate_to_generic_gate_source(unsigned int
 };
 
 static int ni_tio_get_gate_src(struct ni_gpct *counter, 
-                              unsigned int gate_index, lsampl_t * gate_source)
+                              unsigned int gate_index, 
+                              unsigned int * gate_source)
 {
        struct ni_gpct_device *counter_dev = counter->counter_dev;
        const unsigned int mode_bits = ni_tio_get_soft_copy(counter,
@@ -1400,42 +1401,39 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter,
 
 int ni_tio_insn_config(struct ni_gpct *counter, a4l_kinsn_t *insn)
 {
-       switch (insn->data[0]) {
+       unsigned int *data = (unsigned int *)insn->data;
+
+       switch (data[0]) {
        case A4L_INSN_CONFIG_SET_COUNTER_MODE:
-               return ni_tio_set_counter_mode(counter, insn->data[1]);
+               return ni_tio_set_counter_mode(counter, data[1]);
                break;
        case A4L_INSN_CONFIG_ARM:
-               return ni_tio_arm(counter, 1, insn->data[1]);
+               return ni_tio_arm(counter, 1, data[1]);
                break;
        case A4L_INSN_CONFIG_DISARM:
                ni_tio_arm(counter, 0, 0);
                return 0;
                break;
        case A4L_INSN_CONFIG_GET_COUNTER_STATUS:
-               insn->data[1] = ni_tio_counter_status(counter);
-               insn->data[2] = counter_status_mask;
+               data[1] = ni_tio_counter_status(counter);
+               data[2] = counter_status_mask;
                return 0;
                break;
        case A4L_INSN_CONFIG_SET_CLOCK_SRC:
-               return ni_tio_set_clock_src(counter, 
-                                           insn->data[1], insn->data[2]);
+               return ni_tio_set_clock_src(counter, data[1], data[2]);
                break;
        case A4L_INSN_CONFIG_GET_CLOCK_SRC:
-               ni_tio_get_clock_src(counter, 
-                                    &insn->data[1], &insn->data[2]);
+               ni_tio_get_clock_src(counter, &data[1], &data[2]);
                return 0;
                break;
        case A4L_INSN_CONFIG_SET_GATE_SRC:
-               return ni_tio_set_gate_src(counter, 
-                                          insn->data[1], insn->data[2]);
+               return ni_tio_set_gate_src(counter, data[1], data[2]);
                break;
        case A4L_INSN_CONFIG_GET_GATE_SRC:
-               return ni_tio_get_gate_src(counter, 
-                                          insn->data[1], &insn->data[2]);
+               return ni_tio_get_gate_src(counter, data[1], &data[2]);
                break;
        case A4L_INSN_CONFIG_SET_OTHER_SRC:
-               return ni_tio_set_other_src(counter, 
-                                           insn->data[1], insn->data[2]);
+               return ni_tio_set_other_src(counter, data[1], data[2]);
                break;
        case A4L_INSN_CONFIG_RESET:
                ni_tio_reset_count_and_disarm(counter);
@@ -1455,8 +1453,11 @@ int ni_tio_rinsn(struct ni_gpct *counter, a4l_kinsn_t 
*insn)
        unsigned int second_read;
        unsigned int correct_read;
 
-       if (insn->data_size < 1)
-               return 0;
+       uint32_t *data = (uint32_t *)insn->data;
+
+       if (insn->data_size != sizeof(uint32_t))
+               return -EINVAL;
+
        switch (channel) {
        case 0:
                ni_tio_set_bits(counter,
@@ -1485,20 +1486,19 @@ int ni_tio_rinsn(struct ni_gpct *counter, a4l_kinsn_t 
*insn)
                                NITIO_Gi_SW_Save_Reg(counter->counter_index));
                else
                        correct_read = first_read;
-               insn->data[0] = correct_read;
+               data[0] = correct_read;
                return 0;
                break;
        case 1:
-               insn->data[0] =
-                       counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->
-                               counter_index)];
+               data[0] = counter_dev->regs
+                       [NITIO_Gi_LoadA_Reg(counter->counter_index)];
                break;
        case 2:
-               insn->data[0] =
-                       counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->
-                               counter_index)];
+               data[0] = counter_dev->regs
+                       [NITIO_Gi_LoadB_Reg(counter->counter_index)];
                break;
        };
+
        return 0;
 }
 
@@ -1520,8 +1520,11 @@ int ni_tio_winsn(struct ni_gpct *counter, a4l_kinsn_t 
*insn)
        const unsigned int channel = CR_CHAN(insn->chan_desc);
        unsigned int load_reg;
 
-       if (insn->data_size < 1)
-               return 0;
+       uint32_t *data = (uint32_t *)insn->data;
+
+       if (insn->data_size != sizeof(uint32_t))
+               return -EINVAL;
+
        switch (channel) {
        case 0:
                /* Unsafe if counter is armed.  Should probably check
@@ -1529,7 +1532,7 @@ int ni_tio_winsn(struct ni_gpct *counter, a4l_kinsn_t 
*insn)
                /* Don't disturb load source select, just use
                   whichever load register is already selected. */
                load_reg = ni_tio_next_load_register(counter);
-               write_register(counter, insn->data[0], load_reg);
+               write_register(counter, data[0], load_reg);
                ni_tio_set_bits_transient(counter,
                        NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
                        Gi_Load_Bit);
@@ -1539,20 +1542,21 @@ int ni_tio_winsn(struct ni_gpct *counter, a4l_kinsn_t 
*insn)
                break;
        case 1:
                counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] =
-                       insn->data[0];
-               write_register(counter, insn->data[0],
+                       data[0];
+               write_register(counter, data[0],
                        NITIO_Gi_LoadA_Reg(counter->counter_index));
                break;
        case 2:
                counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] =
-                       insn->data[0];
-               write_register(counter, insn->data[0],
+                       data[0];
+               write_register(counter, data[0],
                        NITIO_Gi_LoadB_Reg(counter->counter_index));
                break;
        default:
                return -EINVAL;
                break;
        }
+       
        return 0;
 }
 
diff --git a/ksrc/drivers/analogy/testing/fake.c 
b/ksrc/drivers/analogy/testing/fake.c
index cf22086..9ec3852 100644
--- a/ksrc/drivers/analogy/testing/fake.c
+++ b/ksrc/drivers/analogy/testing/fake.c
@@ -70,14 +70,14 @@ static a4l_cmd_t test_cmd_mask = {
 
 /* --- Analog input simulation --- */
 
-static sampl_t output_tab[8] = { 
+static uint16_t output_tab[8] = { 
        0x0001, 0x2000, 0x4000, 0x6000, 
        0x8000, 0xa000, 0xc000, 0xffff 
 };
 static unsigned int output_idx;
 static a4l_lock_t output_lock = A4L_LOCK_UNLOCKED;
 
-static sampl_t test_output(tstprv_t *priv)
+static uint16_t test_output(tstprv_t *priv)
 {
        unsigned long flags;
        unsigned int idx;
@@ -103,7 +103,7 @@ static void test_task_proc(void *arg)
        a4l_subd_t *subd = a4l_get_subd(dev, TEST_INPUT_SUBD);
        tstprv_t *priv = (tstprv_t *)dev->priv;
        a4l_cmd_t *cmd = NULL;
-       u64 now_ns, elapsed_ns=0;
+       uint64_t now_ns, elapsed_ns=0;
 
        while(!a4l_check_dev(dev))
                a4l_task_sleep(TEST_TASK_PERIOD);
@@ -125,9 +125,9 @@ static void test_task_proc(void *arg)
 
                                for(j = 0; j < cmd->nb_chan; j++)
                                {
-                                       sampl_t value = test_output(priv);
+                                       uint16_t value = test_output(priv);
 
-                                       a4l_buf_put(subd, &value, 
sizeof(sampl_t));
+                                       a4l_buf_put(subd, &value, 
sizeof(uint16_t));
 
                                }
 
@@ -206,10 +206,11 @@ int test_cancel(a4l_subd_t *subd)
 int test_ai_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        tstprv_t *priv = (tstprv_t *)subd->dev->priv;
+       uint16_t *data = (uint16_t *)insn->data;
        int i;
 
-       for(i = 0; i < insn->data_size / sizeof(sampl_t); i++)
-               ((sampl_t*)insn->data)[i] = test_output(priv);
+       for(i = 0; i < insn->data_size / sizeof(uint16_t); i++)
+               data[i] = test_output(priv);
 
        return 0;
 }
@@ -219,8 +220,8 @@ void test_ai_munge(a4l_subd_t *subd, void *buf, unsigned 
long size)
 {
        int i;
 
-       for(i = 0; i < size / sizeof(sampl_t); i++)
-               ((sampl_t*)buf)[i] += 1;
+       for(i = 0; i < size / sizeof(uint16_t); i++)
+               ((uint16_t *)buf)[i] += 1;
 }
 
 void setup_test_subd(a4l_subd_t *subd)
diff --git a/ksrc/drivers/analogy/testing/loop.c 
b/ksrc/drivers/analogy/testing/loop.c
index 14d46c5..1255f54 100644
--- a/ksrc/drivers/analogy/testing/loop.c
+++ b/ksrc/drivers/analogy/testing/loop.c
@@ -45,7 +45,7 @@ struct loop_priv {
 
        /* Misc fields */
        volatile int loop_running:1;
-       sampl_t loop_insn_value;
+       uint16_t loop_insn_value;
 };
 typedef struct loop_priv lpprv_t;
 
@@ -80,13 +80,13 @@ static void loop_task_proc(void *arg)
        while (1) {
        
                if (priv->loop_running) {
-                       sampl_t value;
+                       uint16_t value;
                        int ret=0;
            
                        while (ret==0) {
                
                                ret = a4l_buf_get(output_subd, 
-                                                 &value, sizeof(sampl_t));
+                                                 &value, sizeof(uint16_t));
 
                                if (ret == 0) {
 
@@ -98,7 +98,7 @@ static void loop_task_proc(void *arg)
                    
                                        ret = a4l_buf_put(input_subd, 
                                                          &value, 
-                                                         sizeof(sampl_t));
+                                                         sizeof(uint16_t));
 
                                        if (ret==0)
                                                a4l_buf_evt(input_subd, 0);
@@ -141,13 +141,14 @@ int loop_cancel(a4l_subd_t *subd)
 int loop_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        lpprv_t *priv = (lpprv_t*)subd->dev->priv;
+       uint16_t *data = (uint16_t *)insn->data;
 
        /* Checks the buffer size */
-       if (insn->data_size != sizeof(sampl_t))
+       if (insn->data_size != sizeof(uint16_t))
                return -EINVAL;
 
        /* Sets the memorized value */
-       insn->data[0] = priv->loop_insn_value;
+       data[0] = priv->loop_insn_value;
     
        return 0;
 }
@@ -156,13 +157,14 @@ int loop_insn_read(a4l_subd_t *subd, a4l_kinsn_t *insn)
 int loop_insn_write(a4l_subd_t *subd, a4l_kinsn_t *insn)
 {
        lpprv_t *priv = (lpprv_t*)subd->dev->priv;
+       uint16_t *data = (uint16_t *)insn->data;        
 
        /* Checks the buffer size */
-       if (insn->data_size != sizeof(sampl_t))
+       if (insn->data_size != sizeof(uint16_t))
                return -EINVAL;
 
        /* Retrieves the value to memorize */
-       priv->loop_insn_value = insn->data[0];
+       priv->loop_insn_value = data[0];
     
        return 0;
 }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to