Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/vax/vsa Do 3 retries on a failing sector before giv...



details:   https://anonhg.NetBSD.org/src/rev/6d42863827f6
branches:  trunk
changeset: 493944:6d42863827f6
user:      ragge <ragge%NetBSD.org@localhost>
date:      Tue Jun 27 18:46:17 2000 +0000

description:
Do 3 retries on a failing sector before giving up.
Clear pending interrupts before starting a DMA transfer. If an interrupt
occurs while the HDC9224 is doing DMA, the transfered data will be
scrambled (without giving any errors, quite bad).

diffstat:

 sys/arch/vax/vsa/hdc9224.c |  20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diffs (77 lines):

diff -r 87987bd5e11d -r 6d42863827f6 sys/arch/vax/vsa/hdc9224.c
--- a/sys/arch/vax/vsa/hdc9224.c        Tue Jun 27 18:38:27 2000 +0000
+++ b/sys/arch/vax/vsa/hdc9224.c        Tue Jun 27 18:46:17 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hdc9224.c,v 1.11 2000/06/27 09:09:53 mrg Exp $ */
+/*     $NetBSD: hdc9224.c,v 1.12 2000/06/27 18:46:17 ragge Exp $ */
 /*
  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
  * All rights reserved.
@@ -151,7 +151,9 @@
        int sc_diskblk;                 /* Current block on disk */
        int sc_bytecnt;                 /* How much left to transfer */
        int sc_xfer;                    /* Current transfer size */
+       int sc_retries;
        volatile u_char sc_status;      /* last status from interrupt */
+       char sc_intbit;
 };
 
 struct hdc_attach_args {
@@ -271,6 +273,7 @@
        sc->sc_regs = vax_map_physmem(va->va_paddr, 1);
        sc->sc_dmabase = (caddr_t)va->va_dmaaddr;
        sc->sc_dmasize = va->va_dmasize;
+       sc->sc_intbit = va->va_maskno;
        rd_dmasize = min(MAXPHYS, sc->sc_dmasize); /* Used in rd_minphys */
 
        sc->sc_vd.vd_go = hdc_qstart;
@@ -380,6 +383,11 @@
        if ((sc->sc_status & DKC_ST_TERMCOD) != DKC_TC_SUCCESS) {
                int i;
                u_char *g = (u_char *)&sc->sc_sreg;
+
+               if (sc->sc_retries++ < 3) { /* Allow 3 retries */
+                       hdcstart(sc, bp);
+                       return;
+               }
                printf("%s: failed, status 0x%x\n",
                    sc->sc_dev.dv_xname, sc->sc_status);
                hdc_readregs(sc);
@@ -397,6 +405,8 @@
                vsbus_copytoproc(bp->b_proc, sc->sc_dmabase, sc->sc_bufaddr,
                    sc->sc_xfer);
        }
+       sc->sc_diskblk += (sc->sc_xfer/DEV_BSIZE);
+       sc->sc_bytecnt -= sc->sc_xfer;
        sc->sc_bufaddr += sc->sc_xfer;
 
        if (sc->sc_bytecnt == 0) { /* Finished transfer */
@@ -470,6 +480,7 @@
        struct rdsoftc *rd;
        struct buf *bp;
        int cn, sn, tn, bn, blks;
+       volatile char ch;
 
        if (sc->sc_active)
                return; /* Already doing something */
@@ -483,6 +494,7 @@
                sc->sc_bufaddr = bp->b_data;
                sc->sc_diskblk = bp->b_rawblkno;
                sc->sc_bytecnt = bp->b_bcount;
+               sc->sc_retries = 0;
                bp->b_resid = 0;
        } else
                bp = ob;
@@ -526,8 +538,10 @@
 
        /* Count up vars */
        sc->sc_xfer = blks * DEV_BSIZE;
-       sc->sc_diskblk += blks;
-       sc->sc_bytecnt -= sc->sc_xfer;
+
+       ch = HDC_RSTAT; /* Avoid pending interrupts */
+       WAIT;
+       vsbus_clrintr(sc->sc_intbit); /* Clear pending int's */
 
        if (bp->b_flags & B_READ) {
                HDC_WCMD(DKC_CMD_READ_HDD);



Home | Main Index | Thread Index | Old Index