Subject: port-mac68k/2921: Some SCSI devices do not work in interrupt driven xfer mode
To: None <gnats-bugs@gnats.netbsd.org>
From: Paul Goyette <paul@pgoyette.bdt.com>
List: netbsd-bugs
Date: 11/07/1996 05:48:51
>Number: 2921
>Category: port-mac68k
>Synopsis: Some SCSI devices do not work in interrupt driven xfer mode
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Nov 7 06:05:01 1996
>Last-Modified:
>Originator: Paul Goyette
>Organization:
>Release: Nov 5, 1996
>Environment:
System: NetBSD pgoyette.bdt.com 1.2B NetBSD 1.2B (PGOYETTE) #108:
Tue Nov 5 06:08:28 PST 1996
paul@pgoyette.bdt.com:/home/paul/src/sys/arch/mac68k/compile/PGOYETTE
(current as of Tue Nov 5 04:29:12 1996) mac68k
>Description:
Some devices, such as Exabyte 8200 tape drive, do not work well
in interrupt-driven transfer mode. Mine, for example, always ends
up writing a null (0x00) byte in the next-to-last byte of every
transfer! This is obviously a vagary of the mac68k SCSI hardware
and this using a SCSI "quirk" is not appropriate to fix this, since
quirks are processed in the MI portions of the SCSI drivers.
>How-To-Repeat:
Standard mac68k SCSI driver and Exabyte 8200 - just write to the
tape, then dump the dump!
>Fix:
The patch below implements two new kernel compilation options that,
when defined, force specific SCSI targets to use only the polled
transfer mode. If the options are undefined, the driver behaves
exactlyu as it does without the patch. Two separate options are
defined, one for Reads and one for Writes, since this problem can
occur for one but not the other. (My tape drive only exhibits the
problem on Writes; Reads work just fine in interrupt mode.)
*** /usr/src/sys/arch/mac68k/dev/mac68k5380.c Fri Jun 7 04:39:26 1996
--- /home/paul/src/sys/arch/mac68k/dev/mac68k5380.c Sun Jul 14 10:05:28 1996
***************
*** 123,128 ****
--- 123,148 ----
static volatile u_char *ncr_5380_with_drq = (volatile u_char *) 0x6000;
static volatile u_char *ncr_5380_without_drq = (volatile u_char *) 0x12000;
+ /*
+ * Define flags to force use of pio rather than pdma.
+ * We only define the flags if one or the other is needed
+ * and when we check them in transfer_pdma(), we skip the
+ * check if neither flag is needed.
+ */
+
+ #ifdef NCR_PIO_WRITE
+ #ifdef NCR_PIO_READ
+ static u_int8_t ncr5380_use_pio[2] = { NCR_PIO_WRITE,
+ NCR_PIO_READ };
+ #else /* def NCR_PIO_READ */
+ static u_int8_t ncr5380_use_pio[2] = { NCR_PIO_WRITE, 0 };
+ #endif /* def NCR_PIO_READ */
+ #else /* def NCR_PIO_WRITE */
+ #ifdef NCR_PIO_READ
+ static u_int8_t ncr5380_use_pio[2] = { 0, NCR_PIO_READ };
+ #endif /* def NCR_PIO_READ */
+ #endif /* def NCR_PIO_WRITE */
+
#define SCSI_5380 ((struct scsi_5380 *) ncr)
#define GET_5380_REG(rnum) SCSI_5380->scsi_5380[((rnum)<<4)]
#define SET_5380_REG(rnum,val) (SCSI_5380->scsi_5380[((rnum)<<4)] = (val))
***************
*** 550,558 ****
PID("transfer_pdma0")
/*
! * Don't bother with PDMA if we can't sleep or for small transfers.
*/
! if (reqp->dr_flag & DRIVER_NOINT) {
PID("pdma, falling back to transfer_pio.")
transfer_pio(phasep, data, count, 0);
return -1;
--- 570,583 ----
PID("transfer_pdma0")
/*
! * Don't bother with PDMA if we can't sleep or if
! * target is flagged as needing to use pio.
*/
! if ((reqp->dr_flag & DRIVER_NOINT)
! #if defined(NCR_PIO_READ) || defined(NCR_PIO_WRITE)
! || (ncr5380_use_pio[(*phasep == PH_DATAOUT) ?1 : 0] & (1 << reqp->targ_id))
! #endif
! ) {
PID("pdma, falling back to transfer_pio.")
transfer_pio(phasep, data, count, 0);
return -1;
>Audit-Trail:
>Unformatted: