[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260130170416.49994-36-abbotti@mev.co.uk>
Date: Fri, 30 Jan 2026 16:48:00 +0000
From: Ian Abbott <abbotti@....co.uk>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Ian Abbott <abbotti@....co.uk>,
H Hartley Sweeten <hsweeten@...ionengravers.com>
Subject: [PATCH 35/46] comedi: pcl730: Add sanity checks for I/O base address
The "pcl730" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of various
relay output and digital input ISA board from Advantech, ADLINK, ICP
DAS, and Diamond Systems. It currently allows any base address to be
configured but the hardware devices have restrictions on the base
addresses (configured by on-board DIP switches or jumpers), including
the alignment, which can be larger than the board's I/O register address
span. The Diamond Systems IR104-PBF board is particularly restricted to
4 different base addresses with different sized gaps between the
possible addresses.
Store the minimum supported I/O base addresses and alignment in the
static board information array elements and add a sanity check to ensure
the device is not configured at an unsupported base address. For the
IR104-PBF board, add a special check that the base address is one of the
4 supported base addresses for that board.
Signed-off-by: Ian Abbott <abbotti@....co.uk>
---
drivers/comedi/drivers/pcl730.c | 49 +++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/comedi/drivers/pcl730.c b/drivers/comedi/drivers/pcl730.c
index d2733cd5383d..cf0f97b6e2c0 100644
--- a/drivers/comedi/drivers/pcl730.c
+++ b/drivers/comedi/drivers/pcl730.c
@@ -101,7 +101,9 @@
struct pcl730_board {
const char *name;
- unsigned int io_range;
+ unsigned short io_range;
+ unsigned short min_io_start;
+ unsigned short align_io_start;
unsigned is_pcl725:1;
unsigned is_acl7225b:1;
unsigned is_ir104:1;
@@ -117,6 +119,8 @@ static const struct pcl730_board pcl730_boards[] = {
{
.name = "pcl730",
.io_range = 0x04,
+ .min_io_start = 0,
+ .align_io_start = 0x04,
.has_ttl_io = 1,
.n_subdevs = 4,
.n_iso_out_chan = 16,
@@ -125,6 +129,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "iso730",
.io_range = 0x04,
+ .min_io_start = 0,
+ .align_io_start = 0x04,
.n_subdevs = 4,
.n_iso_out_chan = 16,
.n_iso_in_chan = 16,
@@ -132,6 +138,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "acl7130",
.io_range = 0x08,
+ .min_io_start = 0x200,
+ .align_io_start = 0x08,
.has_ttl_io = 1,
.n_subdevs = 4,
.n_iso_out_chan = 16,
@@ -140,6 +148,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "pcm3730",
.io_range = 0x04,
+ .min_io_start = 0,
+ .align_io_start = 0x04,
.has_ttl_io = 1,
.n_subdevs = 4,
.n_iso_out_chan = 8,
@@ -148,6 +158,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "pcl725",
.io_range = 0x02,
+ .min_io_start = 0x200,
+ .align_io_start = 0x02,
.is_pcl725 = 1,
.n_subdevs = 2,
.n_iso_out_chan = 8,
@@ -155,6 +167,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "p8r8dio",
.io_range = 0x02,
+ .min_io_start = 0,
+ .align_io_start = 0x10,
.is_pcl725 = 1,
.has_readback = 1,
.n_subdevs = 2,
@@ -163,6 +177,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "acl7225b",
.io_range = 0x08, /* only 4 are used */
+ .min_io_start = 0x200,
+ .align_io_start = 0x08,
.is_acl7225b = 1,
.has_readback = 1,
.n_subdevs = 2,
@@ -171,6 +187,8 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "p16r16dio",
.io_range = 0x04,
+ .min_io_start = 0,
+ .align_io_start = 0x08,
.is_acl7225b = 1,
.has_readback = 1,
.n_subdevs = 2,
@@ -179,16 +197,22 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "pcl733",
.io_range = 0x04,
+ .min_io_start = 0,
+ .align_io_start = 0x04,
.n_subdevs = 1,
.n_iso_in_chan = 32,
}, {
.name = "pcl734",
.io_range = 0x04,
+ .min_io_start = 0,
+ .align_io_start = 0x04,
.n_subdevs = 1,
.n_iso_out_chan = 32,
}, {
.name = "opmm-1616-xt",
.io_range = 0x10,
+ .min_io_start = 0x100,
+ .align_io_start = 0x10,
.is_acl7225b = 1,
.has_readback = 1,
.n_subdevs = 2,
@@ -197,11 +221,15 @@ static const struct pcl730_board pcl730_boards[] = {
}, {
.name = "pearl-mm-p",
.io_range = 0x02,
+ .min_io_start = 0x240,
+ .align_io_start = 0x40,
.n_subdevs = 1,
.n_iso_out_chan = 16,
}, {
.name = "ir104-pbf",
.io_range = 0x08,
+ .min_io_start = 0x240,
+ .align_io_start = 0x20,
.is_ir104 = 1,
.has_readback = 1,
.n_iso_out_chan = 20,
@@ -266,10 +294,27 @@ static int pcl730_attach(struct comedi_device *dev,
{
const struct pcl730_board *board = dev->board_ptr;
struct comedi_subdevice *s;
+ unsigned int iobase = it->options[0];
int subdev;
int ret;
- ret = comedi_request_region(dev, it->options[0], board->io_range);
+ if (board->is_ir104) {
+ switch (iobase) {
+ case 0x240:
+ case 0x260:
+ case 0x280:
+ case 0x300:
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: unsupported I/O base address %#x\n",
+ dev->board_name, iobase);
+ return -EINVAL;
+ }
+ }
+ ret = comedi_check_request_region(dev, iobase, board->io_range,
+ board->min_io_start, 0x3ff,
+ board->align_io_start);
if (ret)
return ret;
--
2.51.0
Powered by blists - more mailing lists