linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libata: Fix a large collection of DMA mode mismatches
@ 2008-08-01  8:18 Alan Cox
  2008-08-01 11:56 ` David Müller
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Alan Cox @ 2008-08-01  8:18 UTC (permalink / raw)
  To: David Müller, jgarzik, linux-ide

From: Alan Cox <alan@redhat.com>

Dave Müller sent a diff for the pata_oldpiix that highlighted a problem
where a lot of the ATA drivers assume dma_mode == 0 means "no DMA" while
the core code uses 0xFF.

This turns out to have other consequences such as code doing >= XFER_UDMA_0
also catching 0xFF as UDMAlots. Fortunately it doesn't generally affect
set_dma_mode, although some drivers call back into their own set mode code
from other points.

Having been through the drivers I've added helpers for using_udma/using_mwdma
dma_enabled so that people don't open code ranges that may change (eg if UDMA8
appears somewhere)

Thanks to David for the initial bits

Signed-off-by: Alan Cox <alan@redhat.com>
---

 drivers/ata/libata-core.c |    4 ++--
 drivers/ata/pata_acpi.c   |    2 +-
 drivers/ata/pata_atiixp.c |    2 +-
 drivers/ata/pata_cs5530.c |    6 +++---
 drivers/ata/pata_sc1200.c |    6 +++---
 include/linux/libata.h    |   22 ++++++++++++++++++++++
 6 files changed, 32 insertions(+), 10 deletions(-)


diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b4297ea..d7b6633 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3267,7 +3267,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
 		dev->dma_mode = ata_xfer_mask2mode(dma_mask);
 
 		found = 1;
-		if (dev->dma_mode != 0xff)
+		if (ata_dma_enabled(dev))
 			used_dma = 1;
 	}
 	if (!found)
@@ -3292,7 +3292,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
 
 	/* step 3: set host DMA timings */
 	ata_link_for_each_dev(dev, link) {
-		if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff)
+		if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
 			continue;
 
 		dev->xfer_mode = dev->dma_mode;
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index c5f91e6..783e3c2 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -181,7 +181,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
 
 	if (adev != acpi->last) {
 		pacpi_set_piomode(ap, adev);
-		if (adev->dma_mode)
+		if (ata_dma_enabled(adev))
 			pacpi_set_dmamode(ap, adev);
 		acpi->last = adev;
 	}
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index d7de7ba..e8a0d99 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -183,7 +183,7 @@ static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
 	u16 tmp16;
 
 	pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
-	if (adev->dma_mode >= XFER_UDMA_0)
+	if (ata_using_udma(adev))
 		tmp16 |= (1 << dn);
 	else
 		tmp16 &= ~(1 << dn);
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 744beeb..0c4b271 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -149,10 +149,10 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
 	struct ata_device *prev = ap->private_data;
 
 	/* See if the DMA settings could be wrong */
-	if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
+	if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
 		/* Maybe, but do the channels match MWDMA/UDMA ? */
-		if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
-		    (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
+		if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
+		    (ata_using_udma(prev) && !ata_using_udma(adev)))
 		    	/* Switch the mode bits */
 		    	cs5530_set_dmamode(ap, adev);
 	}
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index cbab397..0278fd2 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -167,10 +167,10 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
 	struct ata_device *prev = ap->private_data;
 
 	/* See if the DMA settings could be wrong */
-	if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
+	if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
 		/* Maybe, but do the channels match MWDMA/UDMA ? */
-		if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
-		    (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
+		if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
+		    (ata_using_udma(prev) && !ata_using_udma(adev)))
 		    	/* Switch the mode bits */
 		    	sc1200_set_dmamode(ap, adev);
 	}
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6820d6b..9bfe49e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1427,6 +1427,28 @@ static inline unsigned long ata_deadline(unsigned long from_jiffies,
 	return from_jiffies + msecs_to_jiffies(timeout_msecs);
 }
 
+/* Don't open code these in drivers as there are traps. Firstly the range may
+   change in future hardware and specs, secondly 0xFF means 'no DMA' but is
+   > UDMA_0. Dyma ddreigiau */
+
+static inline int ata_using_mwdma(struct ata_device *adev)
+{
+	if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
+		return 1;
+	return 0;
+}
+
+static inline int ata_using_udma(struct ata_device *adev)
+{
+	if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
+		return 1;
+	return 0;
+}
+
+static inline int ata_dma_enabled(struct ata_device *adev)
+{
+	return (adev->dma_mode == 0xFF ? 0 : 1);
+}
 
 /**************************************************************************
  * PMP - drivers/ata/libata-pmp.c

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] libata: Fix a large collection of DMA mode mismatches
  2008-08-01  8:18 [PATCH] libata: Fix a large collection of DMA mode mismatches Alan Cox
@ 2008-08-01 11:56 ` David Müller
  2008-08-01 22:42   ` Alan Cox
  2008-08-03  4:45 ` Tejun Heo
  2008-08-22  6:28 ` Jeff Garzik
  2 siblings, 1 reply; 7+ messages in thread
From: David Müller @ 2008-08-01 11:56 UTC (permalink / raw)
  To: Alan Cox; +Cc: jgarzik, linux-ide

Alan Cox wrote:
>  drivers/ata/libata-core.c |    4 ++--
>  drivers/ata/pata_acpi.c   |    2 +-
>  drivers/ata/pata_atiixp.c |    2 +-
>  drivers/ata/pata_cs5530.c |    6 +++---
>  drivers/ata/pata_sc1200.c |    6 +++---
>  include/linux/libata.h    |   22 ++++++++++++++++++++++
>  6 files changed, 32 insertions(+), 10 deletions(-)

A patch for the "pata_oldpiix" driver seems to be missing.

Signed-off-by: Dave Mueller <dave.mueller@gmx.ch>

diff -dpurN a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
--- a/drivers/ata/pata_oldpiix.c    2008-07-14 18:19:53.000000000 +0200
+++ b/drivers/ata/pata_oldpiix.c    2008-08-01 13:17:34.000000000 +0200
@@ -198,7 +198,7 @@ static unsigned int oldpiix_qc_issue(str

  	if (adev != ap->private_data) {
  		oldpiix_set_piomode(ap, adev);
-		if (adev->dma_mode)
+		if (ata_dma_enabled(adev))
  			oldpiix_set_dmamode(ap, adev);
  	}
  	return ata_sff_qc_issue(qc);



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] libata: Fix a large collection of DMA mode mismatches
  2008-08-01 11:56 ` David Müller
@ 2008-08-01 22:42   ` Alan Cox
  0 siblings, 0 replies; 7+ messages in thread
From: Alan Cox @ 2008-08-01 22:42 UTC (permalink / raw)
  To: David Müller; +Cc: jgarzik, linux-ide

On Fri, 01 Aug 2008 13:56:56 +0200
David Müller <dave.mueller@gmx.ch> wrote:

> Alan Cox wrote:
> >  drivers/ata/libata-core.c |    4 ++--
> >  drivers/ata/pata_acpi.c   |    2 +-
> >  drivers/ata/pata_atiixp.c |    2 +-
> >  drivers/ata/pata_cs5530.c |    6 +++---
> >  drivers/ata/pata_sc1200.c |    6 +++---
> >  include/linux/libata.h    |   22 ++++++++++++++++++++++
> >  6 files changed, 32 insertions(+), 10 deletions(-)
> 
> A patch for the "pata_oldpiix" driver seems to be missing.
> 
> Signed-off-by: Dave Mueller <dave.mueller@gmx.ch>

Oops I meant to send that one on as well

Acked-by: Alan Cox <alan@redhat.com>

> diff -dpurN a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
> --- a/drivers/ata/pata_oldpiix.c    2008-07-14 18:19:53.000000000 +0200
> +++ b/drivers/ata/pata_oldpiix.c    2008-08-01 13:17:34.000000000 +0200
> @@ -198,7 +198,7 @@ static unsigned int oldpiix_qc_issue(str
> 
>   	if (adev != ap->private_data) {
>   		oldpiix_set_piomode(ap, adev);
> -		if (adev->dma_mode)
> +		if (ata_dma_enabled(adev))
>   			oldpiix_set_dmamode(ap, adev);
>   	}
>   	return ata_sff_qc_issue(qc);
> 


-- 
--
	"Alan, I'm getting a bit worried about you."
				-- Linus Torvalds

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] libata: Fix a large collection of DMA mode mismatches
  2008-08-01  8:18 [PATCH] libata: Fix a large collection of DMA mode mismatches Alan Cox
  2008-08-01 11:56 ` David Müller
@ 2008-08-03  4:45 ` Tejun Heo
  2008-08-03 13:08   ` Alan Cox
  2008-08-22  6:28 ` Jeff Garzik
  2 siblings, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2008-08-03  4:45 UTC (permalink / raw)
  To: Alan Cox; +Cc: David Müller, jgarzik, linux-ide

Hello, Alan.

Yeap, this approach looks much better.  Just few nits.

Alan Cox wrote:
> @@ -1427,6 +1427,28 @@ static inline unsigned long ata_deadline(unsigned long from_jiffies,
>  	return from_jiffies + msecs_to_jiffies(timeout_msecs);
>  }
>  
> +/* Don't open code these in drivers as there are traps. Firstly the range may
> +   change in future hardware and specs, secondly 0xFF means 'no DMA' but is
> +   > UDMA_0. Dyma ddreigiau */

I suppose "Dyma ddreigiau" is just contamination?  Also, can you please
use similar patch formatting as other comments for consistency?

> +static inline int ata_using_mwdma(struct ata_device *adev)
> +{
> +	if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
> +		return 1;
> +	return 0;
> +}
> +
> +static inline int ata_using_udma(struct ata_device *adev)
> +{
> +	if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
> +		return 1;
> +	return 0;
> +}
> +
> +static inline int ata_dma_enabled(struct ata_device *adev)
> +{
> +	return (adev->dma_mode == 0xFF ? 0 : 1);
> +}

Wouldn't it be better to use ata_using_dma() instead like the other two?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] libata: Fix a large collection of DMA mode mismatches
  2008-08-03  4:45 ` Tejun Heo
@ 2008-08-03 13:08   ` Alan Cox
  2008-08-03 14:02     ` Tejun Heo
  0 siblings, 1 reply; 7+ messages in thread
From: Alan Cox @ 2008-08-03 13:08 UTC (permalink / raw)
  To: Tejun Heo; +Cc: David Müller, jgarzik, linux-ide

> > +/* Don't open code these in drivers as there are traps. Firstly the range may
> > +   change in future hardware and specs, secondly 0xFF means 'no DMA' but is
> > +   > UDMA_0. Dyma ddreigiau */
> 
> I suppose "Dyma ddreigiau" is just contamination?  Also, can you please
> use similar patch formatting as other comments for consistency?

No.. its essetially 'Here by Dragons', and to see if people actually read
patch comments 8)
 
> > +static inline int ata_dma_enabled(struct ata_device *adev)
> > +{
> > +	return (adev->dma_mode == 0xFF ? 0 : 1);
> > +}
> 
> Wouldn't it be better to use ata_using_dma() instead like the other two?

Not really fussed either way. Up to Jeff I guess.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] libata: Fix a large collection of DMA mode mismatches
  2008-08-03 13:08   ` Alan Cox
@ 2008-08-03 14:02     ` Tejun Heo
  0 siblings, 0 replies; 7+ messages in thread
From: Tejun Heo @ 2008-08-03 14:02 UTC (permalink / raw)
  To: Alan Cox; +Cc: David Müller, jgarzik, linux-ide

Alan Cox wrote:
>>> +/* Don't open code these in drivers as there are traps. Firstly the range may
>>> +   change in future hardware and specs, secondly 0xFF means 'no DMA' but is
>>> +   > UDMA_0. Dyma ddreigiau */
>> I suppose "Dyma ddreigiau" is just contamination?  Also, can you please
>> use similar patch formatting as other comments for consistency?
> 
> No.. its essetially 'Here by Dragons', and to see if people actually read
> patch comments 8)

Ah.. Okay.  English word games and Latin phrases scare me.  :-)

>>> +static inline int ata_dma_enabled(struct ata_device *adev)
>>> +{
>>> +	return (adev->dma_mode == 0xFF ? 0 : 1);
>>> +}
>> Wouldn't it be better to use ata_using_dma() instead like the other two?
> 
> Not really fussed either way. Up to Jeff I guess.

The thing is ata_dma_enabled(dev) looks like it's testing whether the
device is capable of doing DMA while 'using' explicitly indicates the
current configuration.  Well, no biggie either way.

-- 
tejun

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] libata: Fix a large collection of DMA mode mismatches
  2008-08-01  8:18 [PATCH] libata: Fix a large collection of DMA mode mismatches Alan Cox
  2008-08-01 11:56 ` David Müller
  2008-08-03  4:45 ` Tejun Heo
@ 2008-08-22  6:28 ` Jeff Garzik
  2 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2008-08-22  6:28 UTC (permalink / raw)
  To: Alan Cox; +Cc: David Müller, linux-ide

Alan Cox wrote:
> From: Alan Cox <alan@redhat.com>
> 
> Dave Müller sent a diff for the pata_oldpiix that highlighted a problem
> where a lot of the ATA drivers assume dma_mode == 0 means "no DMA" while
> the core code uses 0xFF.
> 
> This turns out to have other consequences such as code doing >= XFER_UDMA_0
> also catching 0xFF as UDMAlots. Fortunately it doesn't generally affect
> set_dma_mode, although some drivers call back into their own set mode code
> from other points.
> 
> Having been through the drivers I've added helpers for using_udma/using_mwdma
> dma_enabled so that people don't open code ranges that may change (eg if UDMA8
> appears somewhere)
> 
> Thanks to David for the initial bits
> 
> Signed-off-by: Alan Cox <alan@redhat.com>
> ---
> 
>  drivers/ata/libata-core.c |    4 ++--
>  drivers/ata/pata_acpi.c   |    2 +-
>  drivers/ata/pata_atiixp.c |    2 +-
>  drivers/ata/pata_cs5530.c |    6 +++---
>  drivers/ata/pata_sc1200.c |    6 +++---
>  include/linux/libata.h    |   22 ++++++++++++++++++++++
>  6 files changed, 32 insertions(+), 10 deletions(-)

applied (w/ David's pata_oldpiix update)



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-08-22  6:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-01  8:18 [PATCH] libata: Fix a large collection of DMA mode mismatches Alan Cox
2008-08-01 11:56 ` David Müller
2008-08-01 22:42   ` Alan Cox
2008-08-03  4:45 ` Tejun Heo
2008-08-03 13:08   ` Alan Cox
2008-08-03 14:02     ` Tejun Heo
2008-08-22  6:28 ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).