[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260130170416.49994-14-abbotti@mev.co.uk>
Date: Fri, 30 Jan 2026 16:47:38 +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 13/46] comedi: das16: Add sanity checks for I/O base address
The "das16" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a various
DAS16 compatible boards. It currently allows any base address to be
configured but the hardware only supports base addresses (configured by
an on-board DIP switch) in the range 0 to 0x3f0 on 16- or 32-byte
boundaries. Some of the boards have an 8255 chip at offset 0x10 and
require the board to be configured on a 32-byte boundary unless some
on-board jumpers are set to limit the board to decoding only the first
0x10 registers, disabling access to the 8255. Some other boards place
the 8255 chip (and some other registers) at offset 0x400 from the base
address, decoding 0x10 registers at the base address and 0x8 registers
at the base address plus 0x400.
Add a sanity check to ensure the device is not configured at an
unsupported base address. If the device has the 8255 chip at offset
0x10, and is being configured with the base address at an odd 16-byte
boundary, limit the size of the region to 0x10 and disable the 8255
subdevice.
Signed-off-by: Ian Abbott <abbotti@....co.uk>
---
drivers/comedi/drivers/das16.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/drivers/comedi/drivers/das16.c b/drivers/comedi/drivers/das16.c
index 1f85572c21b4..6eebfda2cb53 100644
--- a/drivers/comedi/drivers/das16.c
+++ b/drivers/comedi/drivers/das16.c
@@ -1018,6 +1018,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct das16_board *board = dev->board_ptr;
struct das16_private_struct *devpriv;
struct comedi_subdevice *s;
+ unsigned int iobase = it->options[0];
unsigned int osc_base;
unsigned int status;
int ret;
@@ -1037,11 +1038,25 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
devpriv->dev = dev;
if (board->size < 0x400) {
- ret = comedi_request_region(dev, it->options[0], board->size);
+ unsigned int size = board->size;
+
+ if (size > 0x10 && (iobase & 0x10) != 0) {
+ /*
+ * The board has more than 0x10 registers and is
+ * being placed on an odd 16-byte boundary. The
+ * board has some jumpers to configure this mode,
+ * disabling the 8255 at offset 0x10, so only 0x10
+ * registers will need to be mapped in this mode.
+ */
+ size = 0x10;
+ }
+ ret = comedi_check_request_region(dev, iobase, size,
+ 0, 0x3ff, 16);
if (ret)
return ret;
} else {
- ret = comedi_request_region(dev, it->options[0], 0x10);
+ ret = comedi_check_request_region(dev, iobase, 0x10,
+ 0, 0x3ff, 16);
if (ret)
return ret;
/* Request an additional region for the 8255 */
@@ -1146,9 +1161,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* 8255 Digital I/O subdevice */
if (board->has_8255) {
s = &dev->subdevices[4];
- ret = subdev_8255_io_init(dev, s, board->i8255_offset);
- if (ret)
- return ret;
+ if (board->i8255_offset == 0x10 && (dev->iobase & 0x10) != 0) {
+ dev_info(dev->class_dev,
+ "Disabling 8255 subdevice on unsupported base address\n");
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ ret = subdev_8255_io_init(dev, s, board->i8255_offset);
+ if (ret)
+ return ret;
+ }
}
das16_reset(dev);
--
2.51.0
Powered by blists - more mailing lists