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: