staging: comedi: addi-data: Don't overwrite read-only data
authorIan Abbott <abbotti@mev.co.uk>
Mon, 16 May 2011 14:28:15 +0000 (15:28 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 17 May 2011 20:33:39 +0000 (13:33 -0700)
The drivers for ADDI-DATA cards can override some static parameters for
the board type using information read from EEPROM.  Unfortunately, they
currently write the parameters from the EEPROM back to the shared,
read-only board data!  The problem has been masked during compilation by
type-casting away the const-ness of the data.

This patch changes the code to use an area in the private data for the
board instance to hold the parameters read from EEPROM (after
initializing the parameters from the static board data).  It also
changes the type-casts to the read-only data to preserve the const
qualifier.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/comedi/drivers/addi-data/addi_common.c
drivers/staging/comedi/drivers/addi-data/addi_common.h
drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c

index 76f2483871a780b6b60140020d686d09218d1980..5776e2085a55a624d50576e83fae93ecabdafa3f 100644 (file)
@@ -77,7 +77,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
 /* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */
 
 #define devpriv ((struct addi_private *)dev->private)
-#define this_board ((struct addi_board *)dev->board_ptr)
+#define this_board ((const struct addi_board *)dev->board_ptr)
 
 #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
 /* BYTE b_SaveFPUReg [94]; */
@@ -2680,6 +2680,21 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
                printk("\nioremap end");
        }
 
+       /* Initialize parameters that can be overridden in EEPROM */
+       devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel;
+       devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel;
+       devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata;
+       devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata;
+       devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel;
+       devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel;
+       devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata;
+       devpriv->s_EeParameters.i_Dma = this_board->i_Dma;
+       devpriv->s_EeParameters.i_Timer = this_board->i_Timer;
+       devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
+               this_board->ui_MinAcquisitiontimeNs;
+       devpriv->s_EeParameters.ui_MinDelaytimeNs =
+               this_board->ui_MinDelaytimeNs;
+
        /* ## */
 
        if (irq > 0) {
@@ -2728,7 +2743,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
                devpriv->us_UseDma = ADDI_ENABLE;
        }
 
-       if (this_board->i_Dma) {
+       if (devpriv->s_EeParameters.i_Dma) {
                printk("\nDMA used");
                if (devpriv->us_UseDma == ADDI_ENABLE) {
                        /*  alloc DMA buffers */
@@ -2787,21 +2802,22 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
                /*  Allocate and Initialise AI Subdevice Structures */
                s = dev->subdevices + 0;
-               if ((this_board->i_NbrAiChannel)
+               if ((devpriv->s_EeParameters.i_NbrAiChannel)
                        || (this_board->i_NbrAiChannelDiff)) {
                        dev->read_subdev = s;
                        s->type = COMEDI_SUBD_AI;
                        s->subdev_flags =
                                SDF_READABLE | SDF_COMMON | SDF_GROUND
                                | SDF_DIFF;
-                       if (this_board->i_NbrAiChannel) {
-                               s->n_chan = this_board->i_NbrAiChannel;
+                       if (devpriv->s_EeParameters.i_NbrAiChannel) {
+                               s->n_chan =
+                                       devpriv->s_EeParameters.i_NbrAiChannel;
                                devpriv->b_SingelDiff = 0;
                        } else {
                                s->n_chan = this_board->i_NbrAiChannelDiff;
                                devpriv->b_SingelDiff = 1;
                        }
-                       s->maxdata = this_board->i_AiMaxdata;
+                       s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
                        s->len_chanlist = this_board->i_AiChannelList;
                        s->range_table = this_board->pr_AiRangelist;
 
@@ -2825,12 +2841,13 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
                /*  Allocate and Initialise AO Subdevice Structures */
                s = dev->subdevices + 1;
-               if (this_board->i_NbrAoChannel) {
+               if (devpriv->s_EeParameters.i_NbrAoChannel) {
                        s->type = COMEDI_SUBD_AO;
                        s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
-                       s->n_chan = this_board->i_NbrAoChannel;
-                       s->maxdata = this_board->i_AoMaxdata;
-                       s->len_chanlist = this_board->i_NbrAoChannel;
+                       s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
+                       s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
+                       s->len_chanlist =
+                               devpriv->s_EeParameters.i_NbrAoChannel;
                        s->range_table = this_board->pr_AoRangelist;
                        s->insn_config =
                                this_board->i_hwdrv_InsnConfigAnalogOutput;
@@ -2841,12 +2858,13 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
                }
                /*  Allocate and Initialise DI Subdevice Structures */
                s = dev->subdevices + 2;
-               if (this_board->i_NbrDiChannel) {
+               if (devpriv->s_EeParameters.i_NbrDiChannel) {
                        s->type = COMEDI_SUBD_DI;
                        s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
-                       s->n_chan = this_board->i_NbrDiChannel;
+                       s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
                        s->maxdata = 1;
-                       s->len_chanlist = this_board->i_NbrDiChannel;
+                       s->len_chanlist =
+                               devpriv->s_EeParameters.i_NbrDiChannel;
                        s->range_table = &range_digital;
                        s->io_bits = 0; /* all bits input */
                        s->insn_config =
@@ -2860,13 +2878,14 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
                }
                /*  Allocate and Initialise DO Subdevice Structures */
                s = dev->subdevices + 3;
-               if (this_board->i_NbrDoChannel) {
+               if (devpriv->s_EeParameters.i_NbrDoChannel) {
                        s->type = COMEDI_SUBD_DO;
                        s->subdev_flags =
                                SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
-                       s->n_chan = this_board->i_NbrDoChannel;
-                       s->maxdata = this_board->i_DoMaxdata;
-                       s->len_chanlist = this_board->i_NbrDoChannel;
+                       s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
+                       s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
+                       s->len_chanlist =
+                               devpriv->s_EeParameters.i_NbrDoChannel;
                        s->range_table = &range_digital;
                        s->io_bits = 0xf;       /* all bits output */
 
@@ -2883,7 +2902,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
                /*  Allocate and Initialise Timer Subdevice Structures */
                s = dev->subdevices + 4;
-               if (this_board->i_Timer) {
+               if (devpriv->s_EeParameters.i_Timer) {
                        s->type = COMEDI_SUBD_TIMER;
                        s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
                        s->n_chan = 1;
index 13621d47037b85e6adcf61f5d89d806e1b8ace93..7165cca25c4d803f1245cba167219a433ae1a600 100644 (file)
@@ -406,7 +406,7 @@ struct addi_private {
 
        /* Pointer to the current process */
        struct task_struct *tsk_Current;
-       struct addi_board *ps_BoardInfo;
+       const struct addi_board *ps_BoardInfo;
 
        /* Hardware board infos for 1710 */
        struct {
@@ -434,6 +434,22 @@ struct addi_private {
        union str_ModuleInfo s_ModuleInfo[4];
        unsigned int ul_TTLPortConfiguration[10];
 
+       /* Parameters read from EEPROM overriding static board info */
+       struct {
+               int i_NbrAiChannel;     /*  num of A/D chans */
+               int i_NbrAoChannel;     /*  num of D/A chans */
+               int i_AiMaxdata;        /*  resolution of A/D */
+               int i_AoMaxdata;        /*  resolution of D/A */
+               int i_NbrDiChannel;     /*  Number of DI channels */
+               int i_NbrDoChannel;     /*  Number of DO channels */
+               int i_DoMaxdata;        /*  data to set all channels high */
+               int i_Dma;              /*  dma present or not */
+               int i_Timer;            /*  timer subdevice present or not */
+               unsigned int ui_MinAcquisitiontimeNs;
+                                       /*  Minimum Acquisition in Nano secs */
+               unsigned int ui_MinDelaytimeNs;
+                                       /*  Minimum Delay in Nano secs */
+       } s_EeParameters;
 };
 
 static unsigned short pci_list_builded;        /* set to 1 when list of card is known */
index 0aa11a0a6e91c05e59220f5546ab5925e4a1feb9..3a9339b926101fc83f4fffaf6bf15438c3327594 100644 (file)
@@ -847,7 +847,7 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
                                pc_PCIChipInformation,
                                s_MainHeader.s_Functions[i].w_Address,
                                &s_DigitalInputHeader);
-                       this_board->i_NbrDiChannel =
+                       devpriv->s_EeParameters.i_NbrDiChannel =
                                s_DigitalInputHeader.w_Nchannel;
                        break;
 
@@ -856,11 +856,12 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
                                pc_PCIChipInformation,
                                s_MainHeader.s_Functions[i].w_Address,
                                &s_DigitalOutputHeader);
-                       this_board->i_NbrDoChannel =
+                       devpriv->s_EeParameters.i_NbrDoChannel =
                                s_DigitalOutputHeader.w_Nchannel;
                        ui_Temp = 0xffffffff;
-                       this_board->i_DoMaxdata =
-                               ui_Temp >> (32 - this_board->i_NbrDoChannel);
+                       devpriv->s_EeParameters.i_DoMaxdata =
+                               ui_Temp >> (32 -
+                                       devpriv->s_EeParameters.i_NbrDoChannel);
                        break;
 
                case EEPROM_ANALOGINPUT:
@@ -869,20 +870,21 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
                                s_MainHeader.s_Functions[i].w_Address,
                                &s_AnalogInputHeader);
                        if (!(strcmp(this_board->pc_DriverName, "apci3200")))
-                               this_board->i_NbrAiChannel =
+                               devpriv->s_EeParameters.i_NbrAiChannel =
                                        s_AnalogInputHeader.w_Nchannel * 4;
                        else
-                               this_board->i_NbrAiChannel =
+                               devpriv->s_EeParameters.i_NbrAiChannel =
                                        s_AnalogInputHeader.w_Nchannel;
-                       this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
-                       this_board->ui_MinAcquisitiontimeNs =
+                       devpriv->s_EeParameters.i_Dma =
+                               s_AnalogInputHeader.b_HasDma;
+                       devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
                                (unsigned int) s_AnalogInputHeader.w_MinConvertTiming *
                                1000;
-                       this_board->ui_MinDelaytimeNs =
+                       devpriv->s_EeParameters.ui_MinDelaytimeNs =
                                (unsigned int) s_AnalogInputHeader.w_MinDelayTiming *
                                1000;
                        ui_Temp = 0xffff;
-                       this_board->i_AiMaxdata =
+                       devpriv->s_EeParameters.i_AiMaxdata =
                                ui_Temp >> (16 -
                                s_AnalogInputHeader.b_Resolution);
                        break;
@@ -892,24 +894,28 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
                                pc_PCIChipInformation,
                                s_MainHeader.s_Functions[i].w_Address,
                                &s_AnalogOutputHeader);
-                       this_board->i_NbrAoChannel =
+                       devpriv->s_EeParameters.i_NbrAoChannel =
                                s_AnalogOutputHeader.w_Nchannel;
                        ui_Temp = 0xffff;
-                       this_board->i_AoMaxdata =
+                       devpriv->s_EeParameters.i_AoMaxdata =
                                ui_Temp >> (16 -
                                s_AnalogOutputHeader.b_Resolution);
                        break;
 
                case EEPROM_TIMER:
-                       this_board->i_Timer = 1;        /* Timer subdevice present */
+                       /* Timer subdevice present */
+                       devpriv->s_EeParameters.i_Timer = 1;
                        break;
 
                case EEPROM_WATCHDOG:
-                       this_board->i_Timer = 1;        /* Timer subdevice present */
+                       /* Timer subdevice present */
+                       devpriv->s_EeParameters.i_Timer = 1;
                        break;
 
                case EEPROM_TIMER_WATCHDOG_COUNTER:
-                       this_board->i_Timer = 1;        /* Timer subdevice present */
+                       /* Timer subdevice present */
+                       devpriv->s_EeParameters.i_Timer = 1;
+                       break;
                }
        }
 
index fc61214151b700a4feed81088e438d387a6fa14b..e886ced4978f84a0ed2d1f10983388a64a41fe3d 100644 (file)
@@ -90,7 +90,8 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
                /* Test the number of the channel */
                for (i = 0; i < data[3]; i++) {
 
-                       if (CR_CHAN(data[4 + i]) >= this_board->i_NbrAiChannel) {
+                       if (CR_CHAN(data[4 + i]) >=
+                               devpriv->s_EeParameters.i_NbrAiChannel) {
                                printk("bad channel list\n");
                                return -2;
                        }
@@ -541,8 +542,10 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
        }
 
        if (cmd->scan_begin_src == TRIG_TIMER) {        /*  Test Delay timing */
-               if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
-                       cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
+               if (cmd->scan_begin_arg <
+                               devpriv->s_EeParameters.ui_MinDelaytimeNs) {
+                       cmd->scan_begin_arg =
+                               devpriv->s_EeParameters.ui_MinDelaytimeNs;
                        err++;
                }
        }
@@ -551,16 +554,18 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
                if (cmd->scan_begin_src == TRIG_TIMER) {
                        if ((cmd->convert_arg)
                                && (cmd->convert_arg <
-                                       this_board->ui_MinAcquisitiontimeNs)) {
-                               cmd->convert_arg =
-                                       this_board->ui_MinAcquisitiontimeNs;
+                                       devpriv->s_EeParameters.
+                                               ui_MinAcquisitiontimeNs)) {
+                               cmd->convert_arg = devpriv->s_EeParameters.
+                                       ui_MinAcquisitiontimeNs;
                                err++;
                        }
                } else {
                        if (cmd->convert_arg <
-                               this_board->ui_MinAcquisitiontimeNs) {
-                               cmd->convert_arg =
-                                       this_board->ui_MinAcquisitiontimeNs;
+                               devpriv->s_EeParameters.ui_MinAcquisitiontimeNs
+                               ) {
+                               cmd->convert_arg = devpriv->s_EeParameters.
+                                       ui_MinAcquisitiontimeNs;
                                err++;
 
                        }
@@ -2452,7 +2457,7 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev,
                                     struct comedi_insn *insn,
                                     unsigned int *data)
 {
-       if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) {
+       if ((data[0] > devpriv->s_EeParameters.i_DoMaxdata) || (data[0] < 0)) {
 
                comedi_error(dev, "Data is not valid !!! \n");
                return -EINVAL;
@@ -2515,7 +2520,7 @@ int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,
                        "Not a valid Data !!! ,Data should be 1 or 0\n");
                return -EINVAL;
        }
-       if (ui_NoOfChannel > this_board->i_NbrDoChannel - 1) {
+       if (ui_NoOfChannel > devpriv->s_EeParameters.i_NbrDoChannel - 1) {
                comedi_error(dev,
                        "This board doesn't have specified channel !!! \n");
                return -EINVAL;
index d3c5963a79e7dbac86fd65cbb8db977bbaa7207c..af6f2c4cb566cf8eee76c8436114dbfe8489a693 100644 (file)
@@ -165,12 +165,16 @@ static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
                 /*******************************/
 
                                if (dw_TestReloadValue >=
-                                       devpriv->ps_BoardInfo->
+                                       devpriv->s_EeParameters.
                                        ui_MinAcquisitiontimeNs) {
                                        if ((b_SingleDiff == APCI3XXX_SINGLE)
                                                || (b_SingleDiff ==
                                                        APCI3XXX_DIFF)) {
-                                               if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
+                                               if (((b_SingleDiff == APCI3XXX_SINGLE)
+                                                       && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
+                                                   || ((b_SingleDiff == APCI3XXX_DIFF)
+                                                       && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))
+                                                   ) {
                           /*******************************/
                                                        /* Single/Diff selection error */
                           /*******************************/
@@ -372,7 +376,7 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
                /* Test the channel number */
           /***************************/
 
-               if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
+               if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
                                && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
                        || ((b_Channel < devpriv->ps_BoardInfo->
                                        i_NbrAiChannelDiff)
@@ -663,7 +667,7 @@ static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
                /* Test the channel number */
           /***************************/
 
-               if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
+               if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
              /**********************************/
                        /* Test the channel configuration */
              /**********************************/
@@ -1273,7 +1277,7 @@ static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
        /* Test the channel number */
        /***************************/
 
-       if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
+       if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) {
           /************************/
                /* Test the buffer size */
           /************************/
@@ -1492,7 +1496,7 @@ static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
                /* Test the channel number */
           /***************************/
 
-               if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+               if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
              /*******************/
                        /* Get the command */
              /*******************/
@@ -1568,7 +1572,7 @@ static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
                /* Test the channel number */
           /***************************/
 
-               if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+               if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
              /********************************/
                        /* Read the digital output port */
              /********************************/