[Soekris] net5501 ATA UDMA mode problem with FreeBSD 7.0

Martin Johnson martin.johnson.uk.lists at googlemail.com
Sun May 25 17:07:16 UTC 2008


> On 24 May 2008, at 16:27, Martin Johnson wrote:
>
>> I'm upgrading a net5501 with a Travelstar E7K100 IDE drive from  
>> FreeBSD 6.2 to 7.0.   FreeBSD 6.2 set the IDE controller up in  
>> UDMA33 mode, but unfortunately 7.0 chooses UDMA100.   From my  
>> tests, the fastest safe setting for this hardware appears to be  
>> UMDA66, as UDMA100 gives  occasional errors such as "ad0: WARNING -  
>> READ_DMA UDMA ICRC error (retrying request) LBA=3871".  This is the  
>> same on comBIOS versions 1.32i and 1.33.
>>
>> Is there any way to force FreeBSD 7.0 to use UDMA66, or failing  
>> that, UDMA33 ?
>> ...
>> It would be nice if /boot/loader.conf had a switch for this...
>
> OK, now it does...   Here is a DIFF against /usr/src/sys/dev/ata/ata- 
> all.c in FreeBSD 7.0-RELEASE.    It adds a sysctl called  
> "hw.ata.ata_dma_limit", which places an upper limit to the ATA UDMA  
> mode that can be used.  With this patch, if you set
> 	hw.ata.ata_dma_limit="4"
> in /boot/loader.conf, then the fastest possible mode will be  
> UDMA66.  The hw.ata.ata_dma_limit setting will never increase the  
> UDMA speed, only decrease it.
>
> Hope this is useful,
>
> - Martin.

It will make for easier reading if I gave a unified DIFF instead.

--- ata-all.c.orig	2008-05-25 17:37:53.000000000 +0100
+++ ata-all.c	2008-05-25 17:37:51.000000000 +0100
@@ -78,6 +78,7 @@

  /* local vars */
  static int ata_dma = 1;
+static int ata_dma_limit = 6;
  static int atapi_dma = 1;

  /* sysctl vars */
@@ -85,6 +86,9 @@
  TUNABLE_INT("hw.ata.ata_dma", &ata_dma);
  SYSCTL_INT(_hw_ata, OID_AUTO, ata_dma, CTLFLAG_RDTUN, &ata_dma, 0,
  	   "ATA disk DMA mode control");
+TUNABLE_INT("hw.ata.ata_dma_limit", &ata_dma_limit);
+SYSCTL_INT(_hw_ata, OID_AUTO, ata_dma_limit, CTLFLAG_RDTUN,  
&ata_dma_limit, 0,
+	   "ATA disk DMA mode limit");
  TUNABLE_INT("hw.ata.atapi_dma", &atapi_dma);
  SYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RDTUN, &atapi_dma, 0,
  	   "ATAPI device DMA mode control");
@@ -900,17 +904,17 @@
  ata_umode(struct ata_params *ap)
  {
      if (ap->atavalid & ATA_FLAG_88) {
-	if (ap->udmamodes & 0x40)
+	if (ap->udmamodes & 0x40  &&  ata_dma_limit >= 6)
  	    return ATA_UDMA6;
-	if (ap->udmamodes & 0x20)
+	if (ap->udmamodes & 0x20  &&  ata_dma_limit >= 5)
  	    return ATA_UDMA5;
-	if (ap->udmamodes & 0x10)
+	if (ap->udmamodes & 0x10  &&  ata_dma_limit >= 4)
  	    return ATA_UDMA4;
-	if (ap->udmamodes & 0x08)
+	if (ap->udmamodes & 0x08  &&  ata_dma_limit >= 3)
  	    return ATA_UDMA3;
-	if (ap->udmamodes & 0x04)
+	if (ap->udmamodes & 0x04  &&  ata_dma_limit >= 2)
  	    return ATA_UDMA2;
-	if (ap->udmamodes & 0x02)
+	if (ap->udmamodes & 0x02  &&  ata_dma_limit >= 1)
  	    return ATA_UDMA1;
  	if (ap->udmamodes & 0x01)
  	    return ATA_UDMA0;



More information about the Soekris-tech mailing list