From 21cc86f936e2d0a8f166d8d6c77c6a46263d22c8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 16 May 2011 15:57:24 +0100 Subject: [PATCH] addi_data: Don't overwrite read-only data 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 --- comedi/drivers/addi-data/addi_common.c | 51 +++++++++++++++-------- comedi/drivers/addi-data/addi_common.h | 18 +++++++- comedi/drivers/addi-data/addi_eeprom.c | 30 ++++++------- comedi/drivers/addi-data/hwdrv_apci3120.c | 18 ++++---- comedi/drivers/addi-data/hwdrv_apci3xxx.c | 14 +++---- 5 files changed, 81 insertions(+), 50 deletions(-) diff --git a/comedi/drivers/addi-data/addi_common.c b/comedi/drivers/addi-data/addi_common.c index 6f65f5e6..cd03a4eb 100644 --- a/comedi/drivers/addi-data/addi_common.c +++ b/comedi/drivers/addi-data/addi_common.c @@ -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 | diff --git a/comedi/drivers/addi-data/addi_common.h b/comedi/drivers/addi-data/addi_common.h index 9f108313..a944404a 100644 --- a/comedi/drivers/addi-data/addi_common.h +++ b/comedi/drivers/addi-data/addi_common.h @@ -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 */ diff --git a/comedi/drivers/addi-data/addi_eeprom.c b/comedi/drivers/addi-data/addi_eeprom.c index cd7d06a9..0aa6a42a 100644 --- a/comedi/drivers/addi-data/addi_eeprom.c +++ b/comedi/drivers/addi-data/addi_eeprom.c @@ -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 } } diff --git a/comedi/drivers/addi-data/hwdrv_apci3120.c b/comedi/drivers/addi-data/hwdrv_apci3120.c index 2375fad3..4f20b5b2 100644 --- a/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -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"); diff --git a/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 6d34a69e..1858b7c3 100755 --- a/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -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 */ /********************************/ -- 2.26.2