2013-09-12 21:01:49

by Ondrej Zary

[permalink] [raw]
Subject: [PATCH] pata_isapnp: Don't use invalid I/O ports

The test for 2nd I/O port validity is broken (reversed):
On devices with no control port, the driver attempts to use invalid port 0,
resulting in logs full of bad_io_access errors.
On devices with control port, the driver does not use it.

Signed-off-by: Ondrej Zary <[email protected]>
---
drivers/ata/pata_isapnp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 4bceb88..b33d1f9 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -78,7 +78,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev

ap->ioaddr.cmd_addr = cmd_addr;

- if (pnp_port_valid(idev, 1) == 0) {
+ if (pnp_port_valid(idev, 1)) {
ctl_addr = devm_ioport_map(&idev->dev,
pnp_port_start(idev, 1), 1);
ap->ioaddr.altstatus_addr = ctl_addr;
--
Ondrej Zary


2013-09-13 18:55:09

by Ondrej Zary

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

On Thursday 12 September 2013 23:01:29 Ondrej Zary wrote:
> The test for 2nd I/O port validity is broken (reversed):
> On devices with no control port, the driver attempts to use invalid port 0,
> resulting in logs full of bad_io_access errors.
> On devices with control port, the driver does not use it.
>
> Signed-off-by: Ondrej Zary <[email protected]>
> ---
> drivers/ata/pata_isapnp.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
> index 4bceb88..b33d1f9 100644
> --- a/drivers/ata/pata_isapnp.c
> +++ b/drivers/ata/pata_isapnp.c
> @@ -78,7 +78,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const
> struct pnp_device_id *dev
>
> ap->ioaddr.cmd_addr = cmd_addr;
>
> - if (pnp_port_valid(idev, 1) == 0) {
> + if (pnp_port_valid(idev, 1)) {
> ctl_addr = devm_ioport_map(&idev->dev,
> pnp_port_start(idev, 1), 1);
> ap->ioaddr.altstatus_addr = ctl_addr;

With this patch, the ATA port works fine if there is a device connected to it.
However, it takes ages to boot if there are no devices connected. Looks like
the driver retries IDENTIFY command for both slave and master drives in a
hope that the devices are there.

log:

[ 7.692344] pata_isapnp 01:01.02: [io 0x01e8-0x01ef]
[ 7.692474] pata_isapnp 01:01.02: [io 0x0168-0x016f]
[ 7.692644] pata_isapnp 01:01.02: [irq 10]
[ 7.695012] pata_isapnp 01:01.02: activated
[ 7.751153] scsi2 : pata_isapnp
[ 7.751781] ata3: PATA max PIO0 cmd 0x168 ctl 0x0 irq 10
[ 12.751446] ata3.01: qc timeout (cmd 0xec)
[ 12.751571] ata3.01: failed to IDENTIFY (I/O error, err_mask=0x5)
[ 22.752270] ata3.01: qc timeout (cmd 0xec)
[ 22.752396] ata3.01: failed to IDENTIFY (I/O error, err_mask=0x5)
[ 52.754737] ata3.01: qc timeout (cmd 0xec)
[ 52.754861] ata3.01: failed to IDENTIFY (I/O error, err_mask=0x5)
[ 57.755149] ata3.00: qc timeout (cmd 0xec)
[ 57.755275] ata3.00: failed to IDENTIFY (I/O error, err_mask=0x5)
[ 67.755974] ata3.00: qc timeout (cmd 0xec)
[ 67.756099] ata3.00: failed to IDENTIFY (I/O error, err_mask=0x5)

--
Ondrej Zary

2013-09-13 21:44:59

by Ondrej Zary

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

On Friday 13 September 2013 20:54:37 Ondrej Zary wrote:
> On Thursday 12 September 2013 23:01:29 Ondrej Zary wrote:
> > The test for 2nd I/O port validity is broken (reversed):
> > On devices with no control port, the driver attempts to use invalid port
> > 0, resulting in logs full of bad_io_access errors.
> > On devices with control port, the driver does not use it.
> >
> > Signed-off-by: Ondrej Zary <[email protected]>
> > ---
> > drivers/ata/pata_isapnp.c | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
> > index 4bceb88..b33d1f9 100644
> > --- a/drivers/ata/pata_isapnp.c
> > +++ b/drivers/ata/pata_isapnp.c
> > @@ -78,7 +78,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const
> > struct pnp_device_id *dev
> >
> > ap->ioaddr.cmd_addr = cmd_addr;
> >
> > - if (pnp_port_valid(idev, 1) == 0) {
> > + if (pnp_port_valid(idev, 1)) {
> > ctl_addr = devm_ioport_map(&idev->dev,
> > pnp_port_start(idev, 1), 1);
> > ap->ioaddr.altstatus_addr = ctl_addr;
>
> With this patch, the ATA port works fine if there is a device connected to
> it. However, it takes ages to boot if there are no devices connected. Looks
> like the driver retries IDENTIFY command for both slave and master drives
> in a hope that the devices are there.
>
> log:
>
> [ 7.692344] pata_isapnp 01:01.02: [io 0x01e8-0x01ef]
> [ 7.692474] pata_isapnp 01:01.02: [io 0x0168-0x016f]
> [ 7.692644] pata_isapnp 01:01.02: [irq 10]
> [ 7.695012] pata_isapnp 01:01.02: activated
> [ 7.751153] scsi2 : pata_isapnp
> [ 7.751781] ata3: PATA max PIO0 cmd 0x168 ctl 0x0 irq 10
> [ 12.751446] ata3.01: qc timeout (cmd 0xec)
> [ 12.751571] ata3.01: failed to IDENTIFY (I/O error, err_mask=0x5)
> [ 22.752270] ata3.01: qc timeout (cmd 0xec)
> [ 22.752396] ata3.01: failed to IDENTIFY (I/O error, err_mask=0x5)
> [ 52.754737] ata3.01: qc timeout (cmd 0xec)
> [ 52.754861] ata3.01: failed to IDENTIFY (I/O error, err_mask=0x5)
> [ 57.755149] ata3.00: qc timeout (cmd 0xec)
> [ 57.755275] ata3.00: failed to IDENTIFY (I/O error, err_mask=0x5)
> [ 67.755974] ata3.00: qc timeout (cmd 0xec)
> [ 67.756099] ata3.00: failed to IDENTIFY (I/O error, err_mask=0x5)

This is caused by skipping ata_sff_softreset() when ap->ioaddr.ctl_addr is
unset so ata_devchk() is never called. This patch seems to fix the problem.
Is it OK or can it cause more problems?

--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2008,13 +2008,15 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,

DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);

- /* software reset. causes dev0 to be selected */
- iowrite8(ap->ctl, ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- iowrite8(ap->ctl, ioaddr->ctl_addr);
- ap->last_ctl = ap->ctl;
+ if (ap->ioaddr.ctl_addr) {
+ /* software reset. causes dev0 to be selected */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+ ap->last_ctl = ap->ctl;
+ }

/* wait the port to become ready */
return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
@@ -2215,10 +2217,6 @@ void ata_sff_error_handler(struct ata_port *ap)

spin_unlock_irqrestore(ap->lock, flags);

- /* ignore ata_sff_softreset if ctl isn't accessible */
- if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
- softreset = NULL;
-
/* ignore built-in hardresets if SCR access is not available */
if ((hardreset == sata_std_hardreset ||
hardreset == sata_sff_hardreset) && !sata_scr_valid(&ap->link))
--
Ondrej Zary

2013-09-22 16:49:48

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

Hello, Ondrej.

On Fri, Sep 13, 2013 at 11:44:27PM +0200, Ondrej Zary wrote:
> This is caused by skipping ata_sff_softreset() when ap->ioaddr.ctl_addr is
> unset so ata_devchk() is never called. This patch seems to fix the problem.
> Is it OK or can it cause more problems?
>
> --- a/drivers/ata/libata-sff.c
> +++ b/drivers/ata/libata-sff.c
> @@ -2008,13 +2008,15 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
>
> DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
>
> - /* software reset. causes dev0 to be selected */
> - iowrite8(ap->ctl, ioaddr->ctl_addr);
> - udelay(20); /* FIXME: flush */
> - iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
> - udelay(20); /* FIXME: flush */
> - iowrite8(ap->ctl, ioaddr->ctl_addr);
> - ap->last_ctl = ap->ctl;
> + if (ap->ioaddr.ctl_addr) {
> + /* software reset. causes dev0 to be selected */
> + iowrite8(ap->ctl, ioaddr->ctl_addr);
> + udelay(20); /* FIXME: flush */
> + iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
> + udelay(20); /* FIXME: flush */
> + iowrite8(ap->ctl, ioaddr->ctl_addr);
> + ap->last_ctl = ap->ctl;
> + }
>
> /* wait the port to become ready */
> return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
> @@ -2215,10 +2217,6 @@ void ata_sff_error_handler(struct ata_port *ap)
>
> spin_unlock_irqrestore(ap->lock, flags);
>
> - /* ignore ata_sff_softreset if ctl isn't accessible */
> - if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
> - softreset = NULL;
> -
> /* ignore built-in hardresets if SCR access is not available */
> if ((hardreset == sata_std_hardreset ||
> hardreset == sata_sff_hardreset) && !sata_scr_valid(&ap->link))

Hmm... I'm unsure what to do with these patches. It's a mostly dead
driver, so I don't wanna mess with it too much unless it's an obvious
fix. What hardware are you playing with?

Thanks.

--
tejun

2013-09-22 19:34:12

by Ondrej Zary

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports



On Sunday 22 September 2013 18:49:42 Tejun Heo wrote:
> Hello, Ondrej.
>
> On Fri, Sep 13, 2013 at 11:44:27PM +0200, Ondrej Zary wrote:
> > This is caused by skipping ata_sff_softreset() when ap->ioaddr.ctl_addr
> > is unset so ata_devchk() is never called. This patch seems to fix the
> > problem. Is it OK or can it cause more problems?
> >
> > --- a/drivers/ata/libata-sff.c
> > +++ b/drivers/ata/libata-sff.c
> > @@ -2008,13 +2008,15 @@ static int ata_bus_softreset(struct ata_port *ap,
> > unsigned int devmask,
> >
> > DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
> >
> > - /* software reset. causes dev0 to be selected */
> > - iowrite8(ap->ctl, ioaddr->ctl_addr);
> > - udelay(20); /* FIXME: flush */
> > - iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
> > - udelay(20); /* FIXME: flush */
> > - iowrite8(ap->ctl, ioaddr->ctl_addr);
> > - ap->last_ctl = ap->ctl;
> > + if (ap->ioaddr.ctl_addr) {
> > + /* software reset. causes dev0 to be selected */
> > + iowrite8(ap->ctl, ioaddr->ctl_addr);
> > + udelay(20); /* FIXME: flush */
> > + iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
> > + udelay(20); /* FIXME: flush */
> > + iowrite8(ap->ctl, ioaddr->ctl_addr);
> > + ap->last_ctl = ap->ctl;
> > + }
> >
> > /* wait the port to become ready */
> > return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
> > @@ -2215,10 +2217,6 @@ void ata_sff_error_handler(struct ata_port *ap)
> >
> > spin_unlock_irqrestore(ap->lock, flags);
> >
> > - /* ignore ata_sff_softreset if ctl isn't accessible */
> > - if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
> > - softreset = NULL;
> > -
> > /* ignore built-in hardresets if SCR access is not available */
> > if ((hardreset == sata_std_hardreset ||
> > hardreset == sata_sff_hardreset) && !sata_scr_valid(&ap->link))
>
> Hmm... I'm unsure what to do with these patches. It's a mostly dead
> driver, so I don't wanna mess with it too much unless it's an obvious
> fix. What hardware are you playing with?

IMHO, the first patch (invalid I/O ports) is an obvious fix. That bug causes
problems with ES968 sound cards.

The second patch is not-so-obvious. Only few ATA controllers don't have
control register, but they're all broken now. I'm not sure if the patch is
100% correct but it seems to work fine and it does not affect most
controllers.

--
Ondrej Zary

2013-09-22 21:42:57

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

On Thu, Sep 12, 2013 at 11:01:29PM +0200, Ondrej Zary wrote:
> The test for 2nd I/O port validity is broken (reversed):
> On devices with no control port, the driver attempts to use invalid port 0,
> resulting in logs full of bad_io_access errors.
> On devices with control port, the driver does not use it.
>
> Signed-off-by: Ondrej Zary <[email protected]>

Applied to libata/for-3.13.

Thanks.

--
tejun

2013-09-23 12:51:24

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

Hello.

On 23-09-2013 1:42, Tejun Heo wrote:

>> The test for 2nd I/O port validity is broken (reversed):
>> On devices with no control port, the driver attempts to use invalid port 0,
>> resulting in logs full of bad_io_access errors.
>> On devices with control port, the driver does not use it.

>> Signed-off-by: Ondrej Zary <[email protected]>

> Applied to libata/for-3.13.

Why only 3.13? Isn't it a simple fix?

> Thanks.

WBR, Sergei

2013-09-23 13:00:47

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

On Mon, Sep 23, 2013 at 04:51:16PM +0400, Sergei Shtylyov wrote:
> >Applied to libata/for-3.13.
>
> Why only 3.13? Isn't it a simple fix?

Hmmm, maybe, the driver is such low impact, I don't think it matters
either way; otherwise, it should be marked -stable too. It's a driver
which shouldn't be enabled by default by distros and I didn't think
it'd be worthwhile to create any traffic for it. That said, if
there's a reason this matters, I'd be happy to add -stable and push it
through ASAP.

Thanks.

--
tejun

2013-09-23 17:13:06

by Ondrej Zary

[permalink] [raw]
Subject: Re: [PATCH] pata_isapnp: Don't use invalid I/O ports

On Monday 23 September 2013 15:00:42 Tejun Heo wrote:
> On Mon, Sep 23, 2013 at 04:51:16PM +0400, Sergei Shtylyov wrote:
> > >Applied to libata/for-3.13.
> >
> > Why only 3.13? Isn't it a simple fix?
>
> Hmmm, maybe, the driver is such low impact, I don't think it matters
> either way; otherwise, it should be marked -stable too. It's a driver
> which shouldn't be enabled by default by distros and I didn't think
> it'd be worthwhile to create any traffic for it. That said, if
> there's a reason this matters, I'd be happy to add -stable and push it
> through ASAP.
>
> Thanks.

At least Debian ships pata_isapnp.ko. Some distros probably stopped building
the driver because it was broken.

--
Ondrej Zary