Subject: [git patches] atang tree: fix UDMA mode for older Promise controllers


DISCLAIMER: the fact of getting patches merged into atang tree means
that from now on they will be getting updates for changes happening
in atang tree and it should not be treated as an indication regarding
decisions taken by 'upstream' kernel trees


Russell King did some great debugging work last month on the root
source of UDMA problems that have been consistenly reported against
pata_pdc202xx_old driver for the last couple of years which should
allow us to hopefully fix them all in atang tree.


On top of atang-v4.4.

The following changes since commit bcf33ade797072b4dcd51dd13b353a6e052036c6:
Thomas Chou (1):
drivers/staging: New PATA driver for Altera CompactFlash.

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/bart/misc.git atang-v4.5

Bartlomiej Zolnierkiewicz (3):
pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards
pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets
pata_pdc202xx_old: update documentation

drivers/ata/Kconfig | 1 -
drivers/ata/pata_pdc202xx_old.c | 13 ++++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)


Subject: [PATCH 3/3] pata_pdc202xx_old: update documentation

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_pdc202xx_old: update documentation

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/Kconfig | 1 -
1 file changed, 1 deletion(-)

Index: b/drivers/ata/Kconfig
===================================================================
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -599,7 +599,6 @@ config PATA_PDC_OLD
20265 and 20267 adapters.

Known issues:
- - UDMA transfers fail mysteriously on some chipsets
- ATAPI DMA is unsupported currently

If unsure, say N.

Subject: [PATCH 1/3] pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards

On Monday 04 January 2010 02:30:24 pm Russell King wrote:

> Found the problem - getting rid of the read of the alt status register
> after the command has been written fixes the UDMA CRC errors on write:
>
> @@ -676,7 +676,8 @@ void ata_sff_exec_command(struct ata_port *ap, const struct
> ata_taskfile *tf)
> DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
>
> iowrite8(tf->command, ap->ioaddr.command_addr);
> - ata_sff_pause(ap);
> + ndelay(400);
> +// ata_sff_pause(ap);
> }
> EXPORT_SYMBOL_GPL(ata_sff_exec_command);
>
>
> This rather makes sense. The PDC20247 handles the UDMA part of the
> protocol. It has no way to tell the PDC20246 to wait while it suspends
> UDMA, so that a normal register access can take place - the 246 ploughs
> on with the register access without any regard to the state of the 247.
>
> If the drive immediately starts the UDMA protocol after a write to the
> command register (as it probably will for the DMA WRITE command), then
> we'll be accessing the taskfile in the middle of the UDMA setup, which
> can't be good. It's certainly a violation of the ATA specs.

Fix it by adding custom ->sff_exec_command method for UDMA33 chipsets.

Debugged-by: Russell King <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_pdc202xx_old.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

Index: b/drivers/ata/pata_pdc202xx_old.c
===================================================================
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -2,7 +2,7 @@
* pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <[email protected]>
- * (C) 2007,2009 Bartlomiej Zolnierkiewicz
+ * (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz
*
* Based in part on linux/drivers/ide/pci/pdc202xx_old.c
*
@@ -26,6 +26,15 @@

#include "pata_pdc202xx_old.h"

+static void pdc20246_exec_command(struct ata_port *ap,
+ const struct ata_taskfile *tf)
+{
+ DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
+
+ iowrite8(tf->command, ap->ioaddr.command_addr);
+ ndelay(400);
+}
+
/**
* pdc2026x_bmdma_start - DMA engine begin
* @qc: ATA command
@@ -171,6 +180,8 @@ static struct ata_port_operations pdc202
.cable_detect = ata_cable_40wire,
.set_piomode = pdc202xx_set_piomode,
.set_dmamode = pdc202xx_set_dmamode,
+
+ .sff_exec_command = pdc20246_exec_command,
};

static struct ata_port_operations pdc2026x_port_ops = {

Subject: [PATCH 2/3] pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets

PDC2026x chipsets need the same treatment as PDC20246 one.

This is completely untested but will hopefully fix UDMA issues
that people have been reporting against pata_pdc202xx_old for
the last couple of years.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_pdc202xx_old.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

Index: b/drivers/ata/pata_pdc202xx_old.c
===================================================================
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -26,7 +26,7 @@

#include "pata_pdc202xx_old.h"

-static void pdc20246_exec_command(struct ata_port *ap,
+static void pdc202xx_exec_command(struct ata_port *ap,
const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
@@ -181,7 +181,7 @@ static struct ata_port_operations pdc202
.set_piomode = pdc202xx_set_piomode,
.set_dmamode = pdc202xx_set_dmamode,

- .sff_exec_command = pdc20246_exec_command,
+ .sff_exec_command = pdc202xx_exec_command,
};

static struct ata_port_operations pdc2026x_port_ops = {

Subject: Re: [PATCH 2/3] pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets

On Saturday 13 February 2010 02:35:59 pm Bartlomiej Zolnierkiewicz wrote:
> From: Bartlomiej Zolnierkiewicz <[email protected]>
> Subject: [PATCH] pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets
>
> PDC2026x chipsets need the same treatment as PDC20246 one.
>
> This is completely untested but will hopefully fix UDMA issues
> that people have been reporting against pata_pdc202xx_old for
> the last couple of years.
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> ---
> drivers/ata/pata_pdc202xx_old.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> Index: b/drivers/ata/pata_pdc202xx_old.c
> ===================================================================
> --- a/drivers/ata/pata_pdc202xx_old.c
> +++ b/drivers/ata/pata_pdc202xx_old.c
> @@ -26,7 +26,7 @@
>
> #include "pata_pdc202xx_old.h"
>
> -static void pdc20246_exec_command(struct ata_port *ap,
> +static void pdc202xx_exec_command(struct ata_port *ap,
> const struct ata_taskfile *tf)
> {
> DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
> @@ -181,7 +181,7 @@ static struct ata_port_operations pdc202
> .set_piomode = pdc202xx_set_piomode,
> .set_dmamode = pdc202xx_set_dmamode,
>
> - .sff_exec_command = pdc20246_exec_command,
> + .sff_exec_command = pdc202xx_exec_command,
> };
>
> static struct ata_port_operations pdc2026x_port_ops = {

the missing chunk :)

@@ -195,6 +195,8 @@
.dev_config = pdc2026x_dev_config,

.port_start = pdc2026x_port_start,
+
+ .sff_exec_command = pdc202xx_exec_command,
};

static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)

2010-02-13 22:39:45

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH 1/3] pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards

On 02/13/2010 08:35 AM, Bartlomiej Zolnierkiewicz wrote:
> From: Bartlomiej Zolnierkiewicz<[email protected]>
> Subject: [PATCH] pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards
>
> On Monday 04 January 2010 02:30:24 pm Russell King wrote:
>
>> Found the problem - getting rid of the read of the alt status register
>> after the command has been written fixes the UDMA CRC errors on write:
>>
>> @@ -676,7 +676,8 @@ void ata_sff_exec_command(struct ata_port *ap, const struct
>> ata_taskfile *tf)
>> DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
>>
>> iowrite8(tf->command, ap->ioaddr.command_addr);
>> - ata_sff_pause(ap);
>> + ndelay(400);
>> +// ata_sff_pause(ap);
>> }
>> EXPORT_SYMBOL_GPL(ata_sff_exec_command);
>>
>>
>> This rather makes sense. The PDC20247 handles the UDMA part of the
>> protocol. It has no way to tell the PDC20246 to wait while it suspends
>> UDMA, so that a normal register access can take place - the 246 ploughs
>> on with the register access without any regard to the state of the 247.
>>
>> If the drive immediately starts the UDMA protocol after a write to the
>> command register (as it probably will for the DMA WRITE command), then
>> we'll be accessing the taskfile in the middle of the UDMA setup, which
>> can't be good. It's certainly a violation of the ATA specs.
>
> Fix it by adding custom ->sff_exec_command method for UDMA33 chipsets.
>
> Debugged-by: Russell King<[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz<[email protected]>
> ---
> drivers/ata/pata_pdc202xx_old.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)

applied

2010-02-13 22:44:15

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH 2/3] pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets

On 02/13/2010 08:44 AM, Bartlomiej Zolnierkiewicz wrote:
> .sff_exec_command = pdc202xx_exec_command,

applied patch #2 + this missing chunk