Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-3]: src/sys/dev/ata Pull up revision 1.82 (requested by thorpej i...
details: https://anonhg.NetBSD.org/src/rev/34c1861abbdd
branches: netbsd-3
changeset: 576507:34c1861abbdd
user: tron <tron%NetBSD.org@localhost>
date: Wed Jul 06 22:03:02 2005 +0000
description:
Pull up revision 1.82 (requested by thorpej in ticket #553):
- When starting an ATA or ATAPI transfer, handle the case where (*dma_init)()
returns EINVAL, indicating that DMA cannot be done for this transfer.
Fall back to PIO in this case.
- Add a geodeide_dma_init() routine that checks to make sure that transfers
start on a 16 byte boundary, returning EINVAL if not. Works around a chip
bug that causes a hard system hang.
Problem reported and patch tested by Erik Fair.
diffstat:
sys/dev/ata/ata_wdc.c | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)
diffs (59 lines):
diff -r 3d176c4c1c5b -r 34c1861abbdd sys/dev/ata/ata_wdc.c
--- a/sys/dev/ata/ata_wdc.c Wed Jul 06 22:02:54 2005 +0000
+++ b/sys/dev/ata/ata_wdc.c Wed Jul 06 22:03:02 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_wdc.c,v 1.79 2005/02/27 00:26:58 perry Exp $ */
+/* $NetBSD: ata_wdc.c,v 1.79.2.1 2005/07/06 22:03:02 tron 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.79 2005/02/27 00:26:58 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.79.2.1 2005/07/06 22:03:02 tron Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@@ -323,7 +323,7 @@
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
u_int16_t cyl;
u_int8_t head, sect, cmd = 0;
- int nblks;
+ int nblks, error;
int dma_flags = 0;
ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
@@ -397,10 +397,21 @@
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READDMA : WDCC_WRITEDMA;
/* Init the DMA channel. */
- if ((*wdc->dma_init)(wdc->dma_arg,
+ error = (*wdc->dma_init)(wdc->dma_arg,
chp->ch_channel, xfer->c_drive,
(char *)xfer->c_databuf + xfer->c_skip,
- ata_bio->nbytes, dma_flags) != 0) {
+ ata_bio->nbytes, dma_flags);
+ if (error) {
+ if (error == EINVAL) {
+ /*
+ * We can't do DMA on this transfer
+ * for some reason. Fall back to
+ * PIO.
+ */
+ xfer->c_flags &= ~C_DMA;
+ error = 0;
+ goto do_pio;
+ }
ata_bio->error = ERR_DMA;
ata_bio->r_error = 0;
wdc_ata_bio_done(chp, xfer);
@@ -437,6 +448,7 @@
/* wait for irq */
goto intr;
} /* else not DMA */
+ do_pio:
ata_bio->nblks = min(nblks, ata_bio->multi);
ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0);
Home |
Main Index |
Thread Index |
Old Index