Subject: kern/1201: Add SCSI ERASE command for tape drives
To: None <gnats-admin@sun-lamp.pc.cs.cmu.edu>
From: Brad Spencer <brad@anduin.eldar.org>
List: netbsd-bugs
Date: 07/09/1995 23:20:03
>Number:         1201
>Category:       kern
>Synopsis:       No support in the kernal for SCSI ERASE on tape drives
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Jul  9 23:20:01 1995
>Originator:     Brad Spencer
>Organization:
	At home
>Release:        as of 7/8/95
>Environment:
	Standard i386 -current
System: NetBSD anduin.eldar.org 1.0A NetBSD 1.0A (ANDUIN) #2: Sun Jul 9 18:49:41 EDT 1995 brad@anduin.eldar.org:/usr/src/sys/arch/i386/compile/ANDUIN i386


>Description:
	There is mention in the include files and in the 'mt' command for
	issuing the SCSI ERASE command to tape drives.  There isn't support
	in the kernal for this operation, however.

>How-To-Repeat:
	Try 'mt -f /dev/.... erase' and be unimpressed.
>Fix:
	Here is support for this operation, based on simular code in the
	FreeBSD kernal.   The command 'cd /sys; patch < this_patch' should
	apply this.  Don't know if I got the 'immediate' stuff exactly
	correct.

diff -c scsi.no_erase/scsi_tape.h scsi/scsi_tape.h
*** scsi.no_erase/scsi_tape.h	Thu Dec 29 06:29:05 1994
p--- scsi/scsi_tape.h	Sun Jul  9 17:51:23 1995
***************
*** 97,102 ****
--- 97,121 ----
  	u_char	control;
  };
  
+ /*
+ ** Tape erase - AKL: Andreas Klemm <andreas@knobel.gun.de>
+ ** Adapted by Brad Spencer <brad@anduin.eldar.org>
+ */
+ #define ERASE                   0x19
+ struct scsi_erase
+ {
+ 	u_char	op_code;
+ 	u_char	byte2;
+ #define	SE_LONG		0x01	/*
+ 				** Archive Viper 2525 doesn't allow short
+ 				** erase, other tapes possibly don't allow
+ 				** that, too.
+ 				*/
+ #define	SE_IMMED	0x02
+ 	u_char	unused[3];
+ 	u_char	control;
+ };
+ 
  #define LOAD			0x1b
  struct scsi_load {
  	u_char	opcode;
diff -c scsi.no_erase/st.c scsi/st.c
*** scsi.no_erase/st.c	Wed Jul  5 02:57:49 1995
--- scsi/st.c	Sun Jul  9 18:49:13 1995
***************
*** 231,236 ****
--- 231,237 ----
  
  int	st_space __P((struct st_softc *, int number, u_int what, int flags));
  int	st_rewind __P((struct st_softc *, u_int immediate, int flags));
+ int	st_erase __P((struct st_softc *, u_int immediate, int flags));
  int	st_mode_sense __P((struct st_softc *, int flags));
  int	st_decide_mode __P((struct st_softc *, boolean first_read));
  int	st_read_block_limits __P((struct st_softc *, int flags));
***************
*** 1081,1086 ****
--- 1082,1090 ----
  		case MTREW:	/* rewind */
  			error = st_rewind(st, 0, flags);
  			break;
+ 		case MTERASE: /* erase */
+ 			error = st_erase(st,0,flags);
+ 			break;
  		case MTOFFL:	/* rewind and put the drive offline */
  			st_unmount(st, EJECT);
  			break;
***************
*** 1580,1585 ****
--- 1584,1628 ----
  	    sizeof(cmd), 0, 0, ST_RETRIES, immediate ? 5000 : 300000, NULL,
  	    flags);
  }
+ 
+ /*
+ **  Erase the device
+ */
+ int
+ st_erase(st, immediate, flags)
+ 	struct st_softc *st;
+ 	u_int immediate;
+ 	int flags;
+ {
+ 	struct scsi_erase cmd;
+ 	int  error;
+ 	int  nmarks;
+ 
+ 	error = st_check_eod(st, FALSE, &nmarks, flags);
+ 	if (error)
+ 	  return (error);
+ 
+ 	/*
+ 	**      Archive Viper 2525 technical manual 5.7 (ERASE 19h):
+ 	**	tape has to be positioned to BOT first before erase command
+ 	**	is issued or command is rejected. So we rewind the tape first
+ 	**	and exit with an error, if the tape can't be rewinded.
+ 	*/
+ 	error = st_rewind(st, 0, SCSI_SILENT);
+ 	if (error)
+ 	  return (error);
+ 	st->flags &= ~ST_PER_ACTION;
+ 
+ 	bzero(&cmd, sizeof(cmd));
+ 	cmd.op_code = ERASE;
+ 	cmd.byte2 = SE_LONG;		/* LONG_ERASE */
+ 	cmd.byte2 += immediate ? SE_IMMED : 0; /* immed bit is here the 2nd! */
+ 	return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
+ 		sizeof(cmd), 0, 0, ST_RETRIES, immediate ? 5000 : 300000,
+ 		NULL,
+ 		flags);
+ }
+ 
  
  /*
   * Look at the returned sense and act on the error and detirmine

>Audit-Trail:
>Unformatted: