Only downgrade modes due to an actual CRC error. Downgrading on other errors
is anti-social -- especially given that there's no way to upgrade again short of rebooting. Also, downgrade UDMA modes more slowly. It's entirely possible that they're using an 80-wire cable, but it's just too long for the higher modes, or there is minor crosstalk.
This commit is contained in:
parent
c7d300d20b
commit
a4135d1d48
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ata_wdc.c,v 1.54 2004/05/08 15:03:32 bouyer Exp $ */
|
||||
/* $NetBSD: ata_wdc.c,v 1.55 2004/06/01 19:32:30 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
|
||||
|
@ -66,7 +66,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.54 2004/05/08 15:03:32 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.55 2004/06/01 19:32:30 mycroft Exp $");
|
||||
|
||||
#ifndef WDCDEBUG
|
||||
#define WDCDEBUG
|
||||
|
@ -613,11 +613,6 @@ wdc_ata_bio_intr(struct wdc_channel *chp, struct ata_xfer *xfer, int irq)
|
|||
printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
|
||||
wdc->sc_dev.dv_xname, chp->ch_channel, xfer->c_drive,
|
||||
xfer->c_bcount, xfer->c_skip);
|
||||
/* if we were using DMA, flag a DMA error */
|
||||
if (xfer->c_flags & C_DMA) {
|
||||
ata_dmaerr(drvp,
|
||||
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
|
||||
}
|
||||
ata_bio->error = TIMEOUT;
|
||||
wdc_ata_bio_done(chp, xfer);
|
||||
return 1;
|
||||
|
@ -661,9 +656,10 @@ wdc_ata_bio_intr(struct wdc_channel *chp, struct ata_xfer *xfer, int irq)
|
|||
drv_err = WDC_ATA_ERR;
|
||||
}
|
||||
}
|
||||
if (ata_bio->r_error & WDCE_CRC)
|
||||
ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
|
||||
if (drv_err != WDC_ATA_ERR)
|
||||
goto end;
|
||||
ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
|
||||
}
|
||||
|
||||
/* if we had an error, end */
|
||||
|
@ -805,14 +801,6 @@ wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
|
|||
if (chp->ch_status & WDCS_ERR) {
|
||||
ata_bio->error = ERROR;
|
||||
ata_bio->r_error = chp->ch_error;
|
||||
if (drvp->drive_flags & DRIVE_UDMA &&
|
||||
(ata_bio->r_error & WDCE_CRC)) {
|
||||
/*
|
||||
* Record the CRC error, to avoid downgrading to
|
||||
* multiword DMA
|
||||
*/
|
||||
drvp->drive_flags |= DRIVE_DMAERR;
|
||||
}
|
||||
if (ata_bio->r_error & (WDCE_BBK | WDCE_UNC | WDCE_IDNF |
|
||||
WDCE_ABRT | WDCE_TK0NF | WDCE_AMNF))
|
||||
return WDC_ATA_ERR;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: atavar.h,v 1.42 2004/05/27 02:23:12 thorpej Exp $ */
|
||||
/* $NetBSD: atavar.h,v 1.43 2004/06/01 19:32:30 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Manuel Bouyer.
|
||||
|
@ -111,7 +111,6 @@ struct ata_drive_datas {
|
|||
#define DRIVE_UDMA 0x0020
|
||||
#define DRIVE_MODE 0x0040 /* the drive reported its mode */
|
||||
#define DRIVE_RESET 0x0080 /* reset the drive state at next xfer */
|
||||
#define DRIVE_DMAERR 0x0100 /* Udma transfer had crc error, don't try DMA */
|
||||
#define DRIVE_ATAPIST 0x0200 /* device is an ATAPI tape drive */
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdc.c,v 1.179 2004/05/27 16:47:35 mycroft Exp $ */
|
||||
/* $NetBSD: wdc.c,v 1.180 2004/06/01 19:32:30 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved.
|
||||
|
@ -70,7 +70,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.179 2004/05/27 16:47:35 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.180 2004/06/01 19:32:30 mycroft Exp $");
|
||||
|
||||
#ifndef WDCDEBUG
|
||||
#define WDCDEBUG
|
||||
|
@ -1541,31 +1541,18 @@ wdc_downgrade_mode(struct ata_drive_datas *drvp, int flags)
|
|||
return 0;
|
||||
|
||||
/*
|
||||
* If we were using Ultra-DMA mode > 2, downgrade to mode 2 first.
|
||||
* Maybe we didn't properly notice the cable type
|
||||
* If we were using Ultra-DMA mode 2, downgrade to mode 1 first.
|
||||
* It helps in some cases.
|
||||
* If we were using Ultra-DMA mode, downgrade to the next lower mode.
|
||||
*/
|
||||
if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode >= 2) {
|
||||
drvp->UDMA_mode = (drvp->UDMA_mode == 2) ? 1 : 2;
|
||||
drvp->UDMA_mode--;
|
||||
printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
|
||||
drv_dev->dv_xname, drvp->UDMA_mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were using ultra-DMA, don't downgrade to multiword DMA
|
||||
* if we noticed a CRC error. It has been noticed that CRC errors
|
||||
* in ultra-DMA lead to silent data corruption in multiword DMA.
|
||||
* Data corruption is less likely to occur in PIO mode.
|
||||
* If we were using ultra-DMA, don't downgrade to multiword DMA.
|
||||
*/
|
||||
else if ((drvp->drive_flags & DRIVE_UDMA) &&
|
||||
(drvp->drive_flags & DRIVE_DMAERR) == 0) {
|
||||
drvp->drive_flags &= ~DRIVE_UDMA;
|
||||
drvp->drive_flags |= DRIVE_DMA;
|
||||
drvp->DMA_mode = drvp->DMA_cap;
|
||||
printf("%s: transfer error, downgrading to DMA mode %d\n",
|
||||
drv_dev->dv_xname, drvp->DMA_mode);
|
||||
} else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
|
||||
else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
|
||||
drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
|
||||
drvp->PIO_mode = drvp->PIO_cap;
|
||||
printf("%s: transfer error, downgrading to PIO mode %d\n",
|
||||
|
|
Loading…
Reference in New Issue