RE: [PATCH 4/5] staging: comedi: comedidev.h: fix comedi_offset_munge() for values > s->maxdata

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

 



On Thursday, August 13, 2015 2:29 AM, Ian Abbott wrote:
> On 13/08/15 01:00, H Hartley Sweeten wrote:
>> The comedi_offset_munge() helper is used to convert unsigned int data
>> values from the comedi offset binary format to two's complement values
>> for hardware that needs the data in that format. The comedi data is
>> always checked against s->maxdata before writing to the hardware so
>> the current implementation always works correctly.
>>
>> It also works to convert the hardware two's complement data into the
>> offset binary format used by comedi. Unfortunately, some boards
>> return extra data in the upper bits. The current implementation
>> ends up leaving these bits in the converted value.
>>
>> Mask the converted value to ensure that any extra bits are removed.
>>
>> Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
>> Cc: Ian Abbott <abbotti@xxxxxxxxx>
>> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
>> ---
>>   drivers/staging/comedi/comedidev.h | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
>> index 28a5d3a..1c8ed5d 100644
>> --- a/drivers/staging/comedi/comedidev.h
>> +++ b/drivers/staging/comedi/comedidev.h
>> @@ -388,7 +388,7 @@ static inline bool comedi_chan_range_is_external(struct comedi_subdevice *s,
>>   static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s,
>>   					       unsigned int val)
>>   {
>> -	return val ^ s->maxdata ^ (s->maxdata >> 1);
>> +	return (val ^ s->maxdata ^ (s->maxdata >> 1)) & s->maxdata;
>>   }
>>
>>   /**
>>
>
> I don't really like this.  I think the function should only be concerned 
> with converting samples between 2's complement and offset binary format 
> and leave any other manipulations up to the driver.  For example, the 
> amplc_pci230 driver needs to right-shift the raw register value from 
> PCI230 in addition to converting from 2's complement (although it does 
> not currently use comedi_offset_munge() to do it).  This change to 
> comedi_offset_munge() also hides whether there may or may not have been 
> extra bits that needed to be stripped.

I disagree.

The drivers should be dealing with any of the "extra" bits and any special shifting
of the data before calling comedi_offset_munge() to convert the data. This is
especially true in the (*insn_read) operations where the samples read from the
hardware are directly added to the returned data:

	val = inx(iobase);
	/* 
	 * Handle any special "extra" bits in the sample data and/or any shifting
	 * of the sample that only the driver knows about.
	 */
	/* return the munged data to the user */
	data[i] = comedi_offset_munge(val);

This way the "val" does not require any extra masking before doing the conversion
and returning the data to the user. The right-shift operation is still handled by the
driver because it's the only one that knows this is needed.

Regards,
Hartley

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



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