addi_data: Don't overwrite read-only data
authorIan Abbott <abbotti@mev.co.uk>
Mon, 16 May 2011 14:57:24 +0000 (15:57 +0100)
committerIan Abbott <abbotti@mev.co.uk>
Mon, 16 May 2011 14:57:24 +0000 (15:57 +0100)
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>
comedi/drivers/addi-data/addi_common.c
comedi/drivers/addi-data/addi_common.h
comedi/drivers/addi-data/addi_eeprom.c
comedi/drivers/addi-data/hwdrv_apci3120.c
comedi/drivers/addi-data/hwdrv_apci3xxx.c

index 6f65f5e6b0162eef65d8f984b48eedefa5d7c32a..cd03a4eb4ba1dbb9e89e413fa256ac4fca5222be 100644 (file)
@@ -77,7 +77,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
 //Update-0.7.57->0.7.68MODULE_LICENSE("GPL");
 
 #define devpriv ((addi_private *)dev->private)
-#define this_board ((boardtype *)dev->board_ptr)
+#define this_board ((const boardtype *)dev->board_ptr)
 
 #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
 //BYTE b_SaveFPUReg [94];
@@ -2643,6 +2643,21 @@ static int i_ADDI_Attach(comedi_device * dev, 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) {
@@ -2691,7 +2706,7 @@ static int i_ADDI_Attach(comedi_device * dev, 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
@@ -2750,21 +2765,21 @@ static int i_ADDI_Attach(comedi_device * dev, 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_RT | 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;
 
@@ -2788,14 +2803,14 @@ static int i_ADDI_Attach(comedi_device * dev, 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 |
                                SDF_RT;
-                       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;
@@ -2806,13 +2821,13 @@ static int i_ADDI_Attach(comedi_device * dev, 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_RT | 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 =
@@ -2826,14 +2841,14 @@ static int i_ADDI_Attach(comedi_device * dev, 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_RT |
                                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 */
 
@@ -2850,7 +2865,7 @@ static int i_ADDI_Attach(comedi_device * dev, 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_RT | SDF_GROUND |
index 9f1083133adcadaccb7ee433e74aa0a3f25193e4..a944404a4db70d08c32ad0365a50d0cfd54af91b 100644 (file)
@@ -435,7 +435,7 @@ typedef struct {
        BYTE b_ExttrigEnable;   //  To enable or disable external trigger
 
        struct task_struct *tsk_Current;        // Pointer to the current process
-       boardtype *ps_BoardInfo;
+       const boardtype *ps_BoardInfo;
 
        // Hardware board infos for 1710
 
@@ -467,6 +467,22 @@ typedef struct {
        str_ModuleInfo s_ModuleInfo[4];
        ULONG 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 */
+               UINT ui_MinAcquisitiontimeNs;
+                                       /*  Minimum Acquisition in Nano secs */
+               UINT ui_MinDelaytimeNs; /*  Minimum Delay in Nano secs */
+       } s_EeParameters;
+
 } addi_private;
 
 static unsigned short pci_list_builded = 0;    /* set to 1 when list of card is known */
index cd7d06a9debd09370758a5371b08147507ac9131..0aa6a42ae86d8a1869eb2082668a7a1b17eea47f 100644 (file)
@@ -849,7 +849,7 @@ INT i_EepromReadMainHeader(WORD 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;
 
@@ -858,11 +858,11 @@ INT i_EepromReadMainHeader(WORD 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:
@@ -871,20 +871,20 @@ INT i_EepromReadMainHeader(WORD 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 =
                                (UINT) s_AnalogInputHeader.w_MinConvertTiming *
                                1000;
-                       this_board->ui_MinDelaytimeNs =
+                       devpriv->s_EeParameters.ui_MinDelaytimeNs =
                                (UINT) 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;
@@ -894,24 +894,24 @@ INT i_EepromReadMainHeader(WORD 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                                        
+                       devpriv->s_EeParameters.i_Timer = 1;    //Timer subdevice present                                        
                        break;
 
                case EEPROM_WATCHDOG:
-                       this_board->i_Timer = 1;        //Timer subdevice present 
+                       devpriv->s_EeParameters.i_Timer = 1;    //Timer subdevice present 
                        break;
 
                case EEPROM_TIMER_WATCHDOG_COUNTER:
-                       this_board->i_Timer = 1;        //Timer subdevice present                               
+                       devpriv->s_EeParameters.i_Timer = 1;    //Timer subdevice present                               
                }
        }
 
index 2375fad3844b9a43b4a27192e225eabcaeb31f86..4f20b5b230e15315407cc426bc98656e31f3978b 100644 (file)
@@ -90,7 +90,7 @@ int i_APCI3120_InsnConfigAnalogInput(comedi_device * dev, comedi_subdevice * s,
                //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;
                        }
@@ -545,8 +545,8 @@ int i_APCI3120_CommandTestAnalogInput(comedi_device * dev, comedi_subdevice * 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++;
                }
        }
@@ -556,16 +556,16 @@ int i_APCI3120_CommandTestAnalogInput(comedi_device * dev, comedi_subdevice * s,
                if (cmd->scan_begin_src == TRIG_TIMER) {
                        if ((cmd->convert_arg)
                                && (cmd->convert_arg <
-                                       this_board->ui_MinAcquisitiontimeNs)) {
+                                       devpriv->s_EeParameters.ui_MinAcquisitiontimeNs)) {
                                cmd->convert_arg =
-                                       this_board->ui_MinAcquisitiontimeNs;
+                                       devpriv->s_EeParameters.ui_MinAcquisitiontimeNs;
                                err++;
                        }
                } else {
                        if (cmd->convert_arg <
-                               this_board->ui_MinAcquisitiontimeNs) {
+                               devpriv->s_EeParameters.ui_MinAcquisitiontimeNs) {
                                cmd->convert_arg =
-                                       this_board->ui_MinAcquisitiontimeNs;
+                                       devpriv->s_EeParameters.ui_MinAcquisitiontimeNs;
                                err++;
 
                        }
@@ -2508,7 +2508,7 @@ int i_APCI3120_InsnConfigDigitalOutput(comedi_device * dev,
 int i_APCI3120_InsnBitsDigitalOutput(comedi_device * dev, comedi_subdevice
        * s, comedi_insn * insn, lsampl_t * 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;
@@ -2569,7 +2569,7 @@ int i_APCI3120_InsnWriteDigitalOutput(comedi_device * dev, comedi_subdevice
                        "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))
                || (ui_NoOfChannel < 0)) {
                comedi_error(dev,
                        "This board doesn't have specified channel !!! \n");
index 6d34a69ea622fe40e20830a2c80fefe88c77f58f..1858b7c3206c1bb92c73c0f18a0c676443e276c0 100755 (executable)
@@ -165,12 +165,12 @@ int i_APCI3XXX_AnalogInputConfigOperatingMode(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 */
                           /*******************************/
@@ -375,7 +375,7 @@ int i_APCI3XXX_InsnReadAnalogInput(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)
@@ -701,7 +701,7 @@ int i_APCI3XXX_InsnWriteAnalogOutput(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 */
              /**********************************/
@@ -1309,7 +1309,7 @@ int i_APCI3XXX_InsnReadDigitalInput(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 */
           /************************/
@@ -1522,7 +1522,7 @@ int i_APCI3XXX_InsnWriteDigitalOutput(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 */
              /*******************/
@@ -1596,7 +1596,7 @@ int i_APCI3XXX_InsnReadDigitalOutput(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 */
              /********************************/