Subject: kern/7252: pcscp timed out on writing to a tape with large blocksize
To: None <gnats-bugs@gnats.netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 03/26/1999 21:34:47
>Number: 7252
>Category: kern
>Synopsis: pcscp timed out on writing to a tape with large blocksize
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Mar 26 08:05:02 1999
>Last-Modified:
>Originator: Izumi Tsutsui
>Organization:
Izumi Tsutsui Himeji City, Japan
>Release: NetBSD-current supped on 19990323
>Environment:
System: NetBSD mirage 1.3K NetBSD 1.3K (MIRAGE) #60: Wed Mar 24 20:49:49 JST \
1999 root@:/usr/src/sys/arch/i386/compile/MIRAGE i386
>Description:
This problem was reported by Roger Brooks <R.S.Brooks@liv.ac.uk>.
According to his report, the pscsp driver got time out message
on writing data to the Exabyte tape drive with >4k blocksize,
though reading tapes with large blocks is no problem.
>How-To-Repeat:
Write large blocks to the tape device on pcscp.
(Although I have no tape devices...)
>Fix:
There were two bugs in pcscp.c.
* resid in pcscp_dma_intr() should also be set in the data out phase.
* Don't set up DMA in the transfer pad operations.
I sent a patch to fix these bugs to Roger, and he have comfirmed
that the problem has been fixed. Thanks, Roger!
The following patch also contains other minor fixes.
* Change URL of the PDF technical manual to the index page.
* include <machine/bswap.h> on big endian machines.
--- sys/dev/pci/pcscp.c.orig Sat Jan 9 21:17:00 1999
+++ sys/dev/pci/pcscp.c Thu Mar 25 21:40:22 1999
@@ -42,7 +42,7 @@
* written by Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
*
* Technical manual available at
- * http://www.amd.com/products/npd/techdocs/19113a.pdf
+ * http://www.amd.com/products/npd/techdocs/techdocs.html
*/
#include <sys/param.h>
@@ -52,6 +52,9 @@
#include <machine/bus.h>
#include <machine/intr.h>
+#if BYTE_ORDER == BIG_ENDIAN
+#include <machine/bswap.h>
+#endif
#include <dev/scsipi/scsi_all.h>
#include <dev/scsipi/scsipi_all.h>
@@ -434,13 +437,20 @@
(NCR_READ_REG(sc, NCR_TCM) << 8),
NCR_READ_REG(sc, NCR_TCL),
NCR_READ_REG(sc, NCR_TCM)));
- WRITE_DMAREG(esc, DMA_CMD, DMACMD_IDLE |
- (datain ? DMACMD_DIR : 0));
- bus_dmamap_unload(esc->sc_dmat, dmap);
return 0;
}
resid = 0;
+ /*
+ * If a transfer onto the SCSI bus gets interrupted by the device
+ * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
+ * as residual since the ESP counter registers get decremented as
+ * bytes are clocked into the FIFO.
+ */
+ if (!datain &&
+ (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+ NCR_DMA(("pcscp_dma_intr: empty esp FIFO of %d ", resid));
+ }
if ((sc->sc_espstat & NCRSTAT_TC) == 0) {
/*
@@ -555,9 +565,11 @@
#endif
/*
- * XXX should handle `Transfer Pad' operation?
+ * No need to set up DMA in `Transfer Pad' operation.
* (case of *dmasize == 0)
*/
+ if (*dmasize == 0)
+ return 0;
error = bus_dmamap_load(esc->sc_dmat, dmap, *esc->sc_dmaaddr,
*esc->sc_dmalen, NULL,
@@ -630,6 +642,10 @@
struct pcscp_softc *esc = (struct pcscp_softc *)sc;
bus_dmamap_t dmap = esc->sc_xfermap, mdldmap = esc->sc_mdldmap;
int datain = esc->sc_datain;
+
+ /* No DMA transfer in Transfer Pad operation */
+ if (esc->sc_dmasize == 0)
+ return;
/* sync transfer buffer */
bus_dmamap_sync(esc->sc_dmat, dmap, 0, dmap->dm_mapsize,
>Audit-Trail:
>Unformatted: