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