Source-Changes-HG archive

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

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



details:   https://anonhg.NetBSD.org/src/rev/90c0b61fed7a
branches:  netbsd-2
changeset: 563805:90c0b61fed7a
user:      riz <riz%NetBSD.org@localhost>
date:      Mon Jul 18 03:57:33 2005 +0000

description:
Pull up revision 1.10 (requested by thorpej in ticket #2072):
- 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 927ba318345f -r 90c0b61fed7a sys/dev/pci/geodeide.c
--- a/sys/dev/pci/geodeide.c    Mon Jul 18 03:36:17 2005 +0000
+++ b/sys/dev/pci/geodeide.c    Mon Jul 18 03:57:33 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: geodeide.c,v 1.1.2.3 2004/07/28 10:56:06 tron Exp $    */
+/*     $NetBSD: geodeide.c,v 1.1.2.3.2.1 2005/07/18 03:57:33 riz Exp $ */
 
 /*
  * Copyright (c) 2004 Manuel Bouyer.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.1.2.3 2004/07/28 10:56:06 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.1.2.3.2.1 2005/07/18 03:57:33 riz 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 wdc_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 *);
@@ -121,6 +122,11 @@
                sc->sc_wdcdev.cap = WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA |
                    WDC_CAPABILITY_IRQACK;
                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.PIO_cap = 4;
        sc->sc_wdcdev.DMA_cap = 2;
@@ -249,3 +255,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