[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