Skip to content

Commit

Permalink
counter: 104-quad-8: Fix race condition between FLAG and CNTR reads
Browse files Browse the repository at this point in the history
commit 4aa3b75 upstream.

The Counter (CNTR) register is 24 bits wide, but we can have an
effective 25-bit count value by setting bit 24 to the XOR of the Borrow
flag and Carry flag. The flags can be read from the FLAG register, but a
race condition exists: the Borrow flag and Carry flag are instantaneous
and could change by the time the count value is read from the CNTR
register.

Since the race condition could result in an incorrect 25-bit count
value, remove support for 25-bit count values from this driver;
hard-coded maximum count values are replaced by a LS7267_CNTR_MAX define
for consistency and clarity.

Fixes: 28e5d3b ("iio: 104-quad-8: Add IIO support for the ACCES 104-QUAD-8")
Cc: <stable@vger.kernel.org> # 6.1.x
Cc: <stable@vger.kernel.org> # 6.2.x
Link: https://lore.kernel.org/r/20230312231554.134858-1-william.gray@linaro.org/
Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
William Breathitt Gray authored and Greg Kroah-Hartman committed Apr 26, 2023
1 parent 8af86ad commit 280b76c
Showing 1 changed file with 1 addition and 13 deletions.
14 changes: 1 addition & 13 deletions drivers/iio/counter/104-quad-8.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ struct quad8_iio {

#define QUAD8_REG_CHAN_OP 0x11
#define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
/* Borrow Toggle flip-flop */
#define QUAD8_FLAG_BT BIT(0)
/* Carry Toggle flip-flop */
#define QUAD8_FLAG_CT BIT(1)
/* Error flag */
#define QUAD8_FLAG_E BIT(4)
/* Up/Down flag */
Expand Down Expand Up @@ -97,9 +93,6 @@ static int quad8_read_raw(struct iio_dev *indio_dev,
{
struct quad8_iio *const priv = iio_priv(indio_dev);
const int base_offset = priv->base + 2 * chan->channel;
unsigned int flags;
unsigned int borrow;
unsigned int carry;
int i;

switch (mask) {
Expand All @@ -110,12 +103,7 @@ static int quad8_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
}

flags = inb(base_offset + 1);
borrow = flags & QUAD8_FLAG_BT;
carry = !!(flags & QUAD8_FLAG_CT);

/* Borrow XOR Carry effectively doubles count range */
*val = (borrow ^ carry) << 24;
*val = 0;

/* Reset Byte Pointer; transfer Counter to Output Latch */
outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
Expand Down

0 comments on commit 280b76c

Please sign in to comment.