Source-Changes-HG archive

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

[src/netbsd-3]: src/sys/dev/pci Pull up revision 1.10 (requested by thorpej i...



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

description:
Pull up revision 1.10 (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/pci/geodeide.c |  25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diffs (57 lines):

diff -r 330c1075a883 -r 3909d911e8ed sys/dev/pci/geodeide.c
--- a/sys/dev/pci/geodeide.c    Wed Jul 06 21:54:24 2005 +0000
+++ b/sys/dev/pci/geodeide.c    Wed Jul 06 22:02:48 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: geodeide.c,v 1.8 2005/02/27 00:27:32 perry Exp $       */
+/*     $NetBSD: geodeide.c,v 1.8.2.1 2005/07/06 22:02:48 tron Exp $    */
 
 /*
  * Copyright (c) 2004 Manuel Bouyer.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.8 2005/02/27 00:27:32 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.8.2.1 2005/07/06 22:02:48 tron Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -54,6 +54,7 @@
 static void geodeide_chip_map(struct pciide_softc *,
                                 struct pci_attach_args *);
 static void geodeide_setup_channel(struct ata_channel *);
+static int geodeide_dma_init(void *, int, int, void *, size_t, int);
 
 static int  geodeide_match(struct device *, struct cfdata *, void *);
 static void geodeide_attach(struct device *, struct device *, void *);
@@ -120,6 +121,11 @@
        if (sc->sc_dma_ok) {
                sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA;
                sc->sc_wdcdev.irqack = pciide_irqack;
+               /*
+                * XXXJRT What chip revisions actually need the DMA
+                * alignment work-around?
+                */
+               sc->sc_wdcdev.dma_init = geodeide_dma_init;
        }
        sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
        sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
@@ -252,3 +258,18 @@
                    idedma_ctl);
        }
 }
+
+static int
+geodeide_dma_init(void *v, int channel, int drive, void *databuf,
+    size_t datalen, int flags)
+{
+
+       /*
+        * If the buffer is not properly aligned, we can't allow DMA
+        * and need to fall back to PIO.
+        */
+       if (((uintptr_t)databuf) & 0xf)
+               return (EINVAL);
+
+       return (pciide_dma_init(v, channel, drive, databuf, datalen, flags));
+}



Home | Main Index | Thread Index | Old Index