The "ni_tio" module contains code to allocate, destroy and operate on a
`struct ni_gpct_device`, which represents a number of counters spread
over one or more blocks (or "chips"). `struct ni_gpct_device` includes
an array member `regs` holding shadow copies of register values.
Unfortunately, this is currently shared by each block of counters so
they interfere with each other. This is a problem for the "ni_660x"
module, which has 8 counters spread over 2 blocks. The `regs` storage
needs to be two-dimensional, indexed by block (chip) number and register
number. (It does not need to be three-dimensional because the registers
for individual counters are intermingled within the block.)
Change the `regs` member to an array pointer that can be indexed like a
two-dimensional array to access the shadow storage for each register in
each block. Allocate the storage in `ni_gpct_device_construct()` and
free it in `ni_gpct_device_destroy()`. (`ni_gpct_device_construct()`
can determine the number of blocks from the `num_counters` and
`counters_per_chip` parameters.)
Add new member `num_chips` to hold the number of chips. Use that to
check that `chip_index` value is in range in the same places that
check the register offset is in range.
Remove the `counters_per_chip` member of `struct ni_gpct_device` as it
is not needed anywhere and could be easily derived from the
`num_counters` and `num_chips` members if required.
Thanks to GitHub user "raabej" (real name unknown) for an initial
implementation of this in the out-of-tree fork of the Comedi drivers.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>