Subject: kern/37108: Timeout during ATAPI tape rewind
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <paul@whooppee.com>
List: netbsd-bugs
Date: 10/11/2007 15:50:00
>Number:         37108
>Category:       kern
>Synopsis:       Timeout during ATAPI tape rewind
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 11 15:50:00 +0000 2007
>Originator:     Paul Goyette
>Release:        NetBSD 4.99.31
>Organization:
>Environment:
System: NetBSD quicky.whooppee.com 4.99.31 NetBSD 4.99.31 (QUICKY (ASUS M2N32 WS) 2007-10-05 16:52:15 UTC) #390: Fri Oct 5 09:56:03 PDT 2007 paul@quicky.whooppee.com:/usr/obj/objdir/amd64/sys/arch/amd64/compile/QUICKY amd64
Architecture: x86_64
Machine: amd64
>Description:
Currently, an ATAPI tape drive is given a maximum of 30 seconds to complete
a rewind operation.  This is insufficient for some tape drives.  The timer
value is selected based on the value of 'immediate', but for ATAPI drives 
this value is modified before being used to select the timer value.

The too-short timer value results in logging lost interrupts.  Further, if
using mt(1) and the "rewoff" command, the rewind operation returns a failure
so the offline operation never happens.
>How-To-Repeat:
Use "mt rewo" command on a slow tape drive.
>Fix:
The following patch calculates the timer value prior to modifying the
'immediate' variable for ATAPI drives.

Index: st.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st.c,v
retrieving revision 1.201
diff -u -p -r1.201 st.c
--- st.c	6 Oct 2007 12:52:43 -0000	1.201
+++ st.c	10 Oct 2007 18:53:05 -0000
@@ -1934,6 +1934,7 @@ st_rewind(struct st_softc *st, u_int imm
 	struct scsi_rewind cmd;
 	int error;
 	int nmarks;
+	int timeout;

 	error = st_check_eod(st, FALSE, &nmarks, flags);
 	if (error) {
@@ -1943,6 +1944,12 @@ st_rewind(struct st_softc *st, u_int imm
 	}
 	st->flags &= ~ST_PER_ACTION;

+	/* If requestor asked for immediate response, set a short timeout */
+	if (immediate)
+		timeout = ST_CTL_TIME;
+	else
+		timeout = ST_SPC_TIME;
+
 	/*
 	 * ATAPI tapes always need immediate to be set
 	 */
@@ -1954,7 +1961,7 @@ st_rewind(struct st_softc *st, u_int imm
 	cmd.byte2 = immediate;

 	error = scsipi_command(st->sc_periph, (void *)&cmd, sizeof(cmd), 0,
0,
-	    ST_RETRIES, immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags);
+	    ST_RETRIES, timeout, NULL, flags);
 	if (error) {
 		printf("%s: error %d trying to rewind\n",
 		    st->sc_dev.dv_xname, error);