Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sys/dev/scsipi Pull up revision 1.95 (requested by thorpe...



details:   https://anonhg.NetBSD.org/src/rev/3d176c4c1c5b
branches:  netbsd-3
changeset: 576506:3d176c4c1c5b
user:      tron <tron%NetBSD.org@localhost>
date:      Wed Jul 06 22:02:54 2005 +0000

description:
Pull up revision 1.95 (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/scsipi/atapi_wdc.c |  25 ++++++++++++++++++-------
 1 files changed, 18 insertions(+), 7 deletions(-)

diffs (54 lines):

diff -r 3909d911e8ed -r 3d176c4c1c5b sys/dev/scsipi/atapi_wdc.c
--- a/sys/dev/scsipi/atapi_wdc.c        Wed Jul 06 22:02:48 2005 +0000
+++ b/sys/dev/scsipi/atapi_wdc.c        Wed Jul 06 22:02:54 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atapi_wdc.c,v 1.92 2005/02/27 00:27:48 perry Exp $     */
+/*     $NetBSD: atapi_wdc.c,v 1.92.2.1 2005/07/06 22:02:54 tron Exp $  */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.92 2005/02/27 00:27:48 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.92.2.1 2005/07/06 22:02:54 tron Exp $");
 
 #ifndef ATADEBUG
 #define ATADEBUG
@@ -611,7 +611,7 @@
        struct scsipi_xfer *sc_xfer = xfer->c_cmd;
        struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
        int len, phase, i, retries=0;
-       int ire;
+       int ire, error;
        int dma_flags = 0;
        void *cmd;
 
@@ -692,11 +692,22 @@
                ATADEBUG_PRINT(("PHASE_CMDOUT\n"), DEBUG_INTR);
                /* Init the DMA channel if necessary */
                if (xfer->c_flags & C_DMA) {
-                       if ((*wdc->dma_init)(wdc->dma_arg,
+                       error = (*wdc->dma_init)(wdc->dma_arg,
                            chp->ch_channel, xfer->c_drive,
-                           xfer->c_databuf, xfer->c_bcount, dma_flags) != 0) {
-                               sc_xfer->error = XS_DRIVER_STUFFUP;
-                               break;
+                           xfer->c_databuf, xfer->c_bcount, 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;
+                               } else {
+                                       sc_xfer->error = XS_DRIVER_STUFFUP;
+                                       break;
+                               }
                        }
                }
 



Home | Main Index | Thread Index | Old Index