From: Ian Abbott Date: Fri, 30 Jan 2026 16:47:38 +0000 (+0000) Subject: comedi: das16: Add sanity checks for I/O base address X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d0c1eee1975b582865b63f66901a6e50fcc6a299;p=thirdparty%2Fkernel%2Flinux.git 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 Link: https://patch.msgid.link/20260130170416.49994-14-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- 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);