Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

comedi: pcl818: Add sanity checks for I/O base address

The "pcl818" driver uses an admin-supplied configuration option
(`it->options[0]`) to configure the I/O port base address of a board in
the PCL-818 series. It currently allows any base address to be
configured but the hardware devices only support base addresses
(configured by on-board DIP switches) from 0 to 0x3F0 on 16-byte
boundaries. If the board has a FIFO and jumper JP6 is in the "Enabled"
(default) position, then the base address needs to be on a 32-byte
boundary and the length of the I/O port region will be 32 (to allow
access to the FIFO registers) instead of 16. The state of jumper JP6 is
unknown, so if the board has a FIFO device and is being configured on an
odd 16-byte boundary, assume that jumper JP6 is in the "Disabled"
position (to disallow access to the FIFO registers).

Add a sanity check to ensure the device is not configured at an
unsupported base address.

If the board has a FIFO and is configured on an odd 16-byte boundary,
log a reminder that JP6 needs to be in the "Disabled" position for
correct operation. If the board has a FIFO and is configured on an even
16-byte boundary and the configuration option has been set to use the
FIFO (`it->options[2] == -1`), log a reminder that JP6 needs to be in
the "Enabled" position.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260130170416.49994-39-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ian Abbott and committed by
Greg Kroah-Hartman
aaddeab2 55e39df1

+24 -3
+24 -3
drivers/comedi/drivers/pcl818.c
··· 981 981 const struct pcl818_board *board = dev->board_ptr; 982 982 struct pcl818_private *devpriv; 983 983 struct comedi_subdevice *s; 984 + unsigned int io_base = it->options[0]; 985 + bool fifo_is_supported = board->has_fifo && !(io_base & 0x10); 986 + bool fifo_is_wanted = board->has_fifo && it->options[2] == -1; 987 + unsigned int io_len = fifo_is_supported ? 0x20 : 0x10; 984 988 unsigned int osc_base; 985 989 int ret; 986 990 ··· 992 988 if (!devpriv) 993 989 return -ENOMEM; 994 990 995 - ret = comedi_request_region(dev, it->options[0], 996 - board->has_fifo ? 0x20 : 0x10); 991 + ret = comedi_check_request_region(dev, io_base, io_len, 992 + 0, 0x3ff, io_len); 997 993 if (ret) 998 994 return ret; 995 + 996 + if (board->has_fifo) { 997 + /* let user know about any required JP6 setting */ 998 + if (fifo_is_supported) { 999 + if (fifo_is_wanted) { 1000 + dev_info(dev->class_dev, 1001 + "Assuming JP6 is in \"Enabled\" (default) position to use the FIFO.\n"); 1002 + } 1003 + } else { 1004 + dev_info(dev->class_dev, 1005 + "JP6 needs to be in \"Disabled\" position for correct operation at this base address\n"); 1006 + if (fifo_is_wanted) { 1007 + dev_warn(dev->class_dev, 1008 + "FIFO cannot be used at this base address\n"); 1009 + } 1010 + } 1011 + } 999 1012 1000 1013 /* we can use IRQ 2-7 for async command support */ 1001 1014 if (it->options[1] >= 2 && it->options[1] <= 7) { ··· 1023 1002 } 1024 1003 1025 1004 /* should we use the FIFO? */ 1026 - if (dev->irq && board->has_fifo && it->options[2] == -1) 1005 + if (dev->irq && fifo_is_supported && fifo_is_wanted) 1027 1006 devpriv->usefifo = 1; 1028 1007 1029 1008 /* we need an IRQ to do DMA on channel 3 or 1 */