Re: [PATCH 1/2] ata: pata_artop: read the ATP865 mode register through pci_iomap

From: Damien Le Moal

Date: Thu Oct 22 2026 - 03:01:34 EST


On 2026/10/17 6:14, Daniel Palmer wrote:
> artop_init_one() probes the 6280's "fast" bit with inb() on the raw
> start address of BAR 4. That address is a PCI I/O address, which is
> only a usable port number on platforms whose I/O port base maps PCI I/O
> space one to one. On an SH7751 LANDISK (identity io_port_base, PCI I/O
> window at 0xfe240000) the resource starts at 0x1400 and inb(0x1400)
> dereferences that address:
>
> BUG: unable to handle kernel paging request at 00001400
> PC is at artop_init_one+0x10e/0x170
>
> Map the BAR with pci_iomap() and use ioread8(), as libata-sff does for
> the BMDMA registers later on.
>
> Signed-off-by: Daniel Palmer <daniel@xxxxxxxx>
> ---
> drivers/ata/pata_artop.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
> index 9f8d41639a62..351ff4c8e48e 100644
> --- a/drivers/ata/pata_artop.c
> +++ b/drivers/ata/pata_artop.c
> @@ -405,13 +405,21 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
> case 1: /* 6260 */
> ppi[0] = &info_626x;
> break;
> - case 2: /* 6280 or 6280 + fast */
> - if (inb(pci_resource_start(pdev, 4)) & 0x10)
> + case 2: { /* 6280 or 6280 + fast */
> + void __iomem *bmdma = pci_iomap(pdev, 4, 1);
> + u8 cfg;
> +
> + if (!bmdma)
> + return -ENOMEM;
> + cfg = ioread8(bmdma);
> + pci_iounmap(pdev, bmdma);
> + if (cfg & 0x10)
> ppi[0] = &info_628x_fast;
> else
> ppi[0] = &info_628x;
> break;
> }
> + }

This is really ugly... Please move the "case 2" variable declarations to the top
of the function so that you do not have to do something like this.

Of note also is that this switch does not have a "default" case, which is really
bad practice, even though in this case, we should never hit unknown values.
But I would still prefer seeing something like:

default:
pr_warn("Invalid driver data\n");
pci_disable_device(pdev);
return -ENODEV;
}

or a big hammer:

default:
BUG();
}

>
> BUG_ON(ppi[0] == NULL);
>


--
Damien Le Moal
Western Digital Research