diff --git a/README b/README index 6ef6554..df768f2 100644 --- a/README +++ b/README @@ -29,6 +29,12 @@ Installation: - make - make install +Changes in version 0.9b: +- only stinit changed + +Changes in version 0.9: +- more density codes + Changes in version 0.8: - put man page into /usr/share/man/man1 - documentation cleanup @@ -87,4 +93,4 @@ Changes in version 0.3: by the command compression using a new ioctl) - bus fixes -April 13, 2004 Kai Makisara (email Kai.Makisara@kolumbus.fi) +May 29, 2005 Kai Makisara (email Kai.Makisara@kolumbus.fi) diff --git a/README.stinit b/README.stinit index c187557..2db7fc5 100644 --- a/README.stinit +++ b/README.stinit @@ -1,7 +1,10 @@ The program stinit is meant for initializing of SCSI tape drive modes at system startup, when the tape driver module is loaded, or when new tape drivers are initialized using -echo "scsi add-single-device" x y z v >/proc/scsi/scsi +echo "scsi add-single-device x y z v" >/proc/scsi/scsi +or (with 2.6 kernels) +echo "y z v" > /sys/class/scsi_host/hostx/scan +where x=host y=channel z=id v=lun (- is wild card for 2.6). The parameters used in initialization of a tape drive are fetched from a text file. The parameter file is indexed by the inquiry data @@ -31,6 +34,14 @@ stinit.def.examples - a file containing example definitions for Makefile - a sample makefile for the program README.stinit - this file +Changes in version 0.9b: +- fix back out to SCSI_IOCTL_SEND_COMMAND for 2.4 kernels (2.4 uses errno + EINVAL for unsupported ioctls) + +Changes in version 0.9: +- try first SG_IO for inquiry, if the ioctl fails, try SCSI_IOCTL_SEND_COMMAND + - error checking for SG_IO is very simplistic for now + Changes in version 0.8: - in devfs, /dev/tapes/tape does not match th drive after rmmoding and insmodding the st driver; fix provided by Philippe Troin @@ -53,5 +64,5 @@ Changes in version 0.6: Initial version 0.5. -April 13, 2004 Kai Mäkisara +May 29, 2005 Kai Mäkisara diff --git a/mt-st-0.8.lsm b/mt-st-0.9b.lsm similarity index 71% rename from mt-st-0.8.lsm rename to mt-st-0.9b.lsm index 4138bbf..5b16601 100644 --- a/mt-st-0.8.lsm +++ b/mt-st-0.9b.lsm @@ -1,16 +1,16 @@ Begin4 Title: mt-st -Version: 0.8 -Entered-date: 2004-04-13 +Version: 0.9b +Entered-date: 2005-08-21 Description: Magnetic tape control tools for Linux SCSI tapes. Includes a mt-like program supporting additional commands using ioctls -specific to the Linux SCSI tape driver (up to kernel 2.6.5), and the program +specific to the Linux SCSI tape driver (up to kernel 2.6.12), and the program stinit to define the SCSI tape devices in system startup scripts. Keywords: tape SCSI Author: Kai.Makisara@kolumbus.fi (Kai Makisara) Maintained-by: Kai.Makisara@kolumbus.fi (Kai Makisara) Primary-site: ftp://ftp.ibiblio.org/pub/linux/system/backup - 35 kB mt-st-0.8.tar.gz - 0.7 kB mt-st-0.8.lsm + 37 kB mt-st-0.9b.tar.gz + 0.7 kB mt-st-0.9b.lsm Copying-policy: GPL End diff --git a/mt.1 b/mt.1 index dfd10cc..72630e1 100644 --- a/mt.1 +++ b/mt.1 @@ -1,4 +1,4 @@ -.TH MT 1 "April 2004" \" -*- nroff -*- +.TH MT 1 "August 2005" \" -*- nroff -*- .SH NAME mt \- control magnetic tape drive operation .SH SYNOPSIS @@ -268,7 +268,7 @@ failed. .SH AUTHOR The program is written by Kai Makisara . .SH COPYRIGHT -The program and the manual page are copyrighted by Kai Makisara, 1998-2004. +The program and the manual page are copyrighted by Kai Makisara, 1998-2005. They can be distributed according to the GNU Copyleft. .SH SEE ALSO st(4) diff --git a/mt.c b/mt.c index 34346a8..53cfc31 100644 --- a/mt.c +++ b/mt.c @@ -5,10 +5,10 @@ tape drive. Maintained by Kai Mäkisara (email Kai.Makisara@kolumbus.fi) - Copyright by Kai Mäkisara, 1998 - 2004. The program may be distributed + Copyright by Kai Mäkisara, 1998 - 2005. The program may be distributed according to the GNU Public License - Last Modified: Tue Apr 13 21:26:24 2004 by makisara + Last Modified: Sun Aug 21 21:48:06 2005 by kai.makisara */ #include @@ -27,7 +27,7 @@ #define DEFTAPE "/dev/tape" /* default tape device */ #endif /* DEFTAPE */ -#define VERSION "0.8" +#define VERSION "0.9b" typedef int (* cmdfunc)(/* int, struct cmdef_tr *, int, char ** */); @@ -214,7 +214,8 @@ static struct densities { {0x33, "SLR6"}, {0x34, "SLR100"}, {0x40, "DLT1 40 GB, or Ultrium"}, - {0x41, "DLT 40GB"}, + {0x41, "DLT 40GB, or Ultrium2"}, + {0x42, "LTO-2"}, {0x45, "QIC-3095-MC (TR-4)"}, {0x47, "TR-5"}, {0x80, "DLT 15GB uncomp. or Ecrix"}, diff --git a/stinit.8 b/stinit.8 index 8a9d75e..341c185 100644 --- a/stinit.8 +++ b/stinit.8 @@ -1,4 +1,4 @@ -.TH STINIT 8 "April 2004" \" -*- nroff -*- +.TH STINIT 8 "August 2005" \" -*- nroff -*- .SH NAME stinit \- initialize SCSI magnetic tape drives .SH SYNOPSIS @@ -266,7 +266,7 @@ for the superuser. .SH AUTHOR The program is written by Kai Makisara . .SH COPYRIGHT -The program and the manual page are copyrighted by Kai Makisara, 1998-2004. +The program and the manual page are copyrighted by Kai Makisara, 1998-2005. They can be distributed according to the GNU Copyleft. .SH SEE ALSO st(4) mt(1) diff --git a/stinit.c b/stinit.c index 8907ad5..fa18860 100644 --- a/stinit.c +++ b/stinit.c @@ -1,11 +1,11 @@ /* This program initializes Linux SCSI tape drives using the inquiry data from the devices and a text database. - Copyright 1996-2004 by Kai Mäkisara (email Kai.Makisara@kolumbus.fi) + Copyright 1996-2005 by Kai Mäkisara (email Kai.Makisara@kolumbus.fi) Distribution of this program is allowed according to the GNU Public Licence. - Last modified: Tue Apr 13 21:26:42 2004 by makisara + Last modified: Sun Aug 21 21:47:51 2005 by kai.makisara */ #include @@ -20,6 +20,7 @@ #include #include #include +#include #include "mtio.h" @@ -29,7 +30,7 @@ #endif #define SKIP_WHITE(p) for ( ; *p == ' ' || *p == '\t'; p++) -#define VERSION "0.8" +#define VERSION "0.9b" typedef struct _modepar_tr { int defined; @@ -444,7 +445,22 @@ find_pars(FILE *dbf, char *company, char *product, char *rev, devdef_tr *defs, } +static int sg_io_errcheck(struct sg_io_hdr *hdp) +{ + int status; + + status = hdp->status & 0x7e; + if ((hdp->status & 0x7e) == 0 || hdp->host_status == 0 || + hdp->driver_status == 0) + return 0; + return EIO; +} + + #define INQUIRY 0x12 +#define INQUIRY_CMDLEN 6 +#define SENSE_BUFF_LEN 32 +#define DEF_TIMEOUT 60000 #ifndef SCSI_IOCTL_SEND_COMMAND #define SCSI_IOCTL_SEND_COMMAND 1 @@ -457,7 +473,10 @@ do_inquiry(char *tname, char *company, char *product, char *rev, int print_non_f int fn; int result, *ip, i; #define BUFLEN 256 - unsigned char buffer[BUFLEN], *cmd; + unsigned char buffer[BUFLEN], *cmd, *inqptr; + struct sg_io_hdr io_hdr; + unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY, 0, 0, 0, 200, 0}; + unsigned char sense_b[SENSE_BUFF_LEN]; if ((fn = open(tname, O_RDONLY | O_NONBLOCK)) < 0) { if (print_non_found || verbose > 0) { @@ -470,34 +489,55 @@ do_inquiry(char *tname, char *company, char *product, char *rev, int print_non_f return FALSE; } - memset(buffer, 0, BUFLEN); - ip = (int *)&(buffer[0]); - *ip = 0; - *(ip+1) = BUFLEN - 13; + /* Try SG_IO first, if it is not supported, use SCSI_IOCTL_SEND_COMMAND */ + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof(inqCmdBlk); + io_hdr.mx_sb_len = sizeof(sense_b); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = 200; + io_hdr.dxferp = buffer; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sense_b; + io_hdr.timeout = DEF_TIMEOUT; + inqptr = buffer; - cmd = &(buffer[8]); - cmd[0] = INQUIRY; - cmd[4] = 200; - - result = ioctl(fn, SCSI_IOCTL_SEND_COMMAND, buffer); + result = ioctl(fn, SG_IO, &io_hdr); + if (!result) + result = sg_io_errcheck(&io_hdr); if (result) { - close(fn); - sprintf(buffer, - "The SCSI INQUIRY for device '%s' failed (power off?)", - tname); - perror(buffer); - return FALSE; + if (errno == ENOTTY || errno == EINVAL) { + memset(buffer, 0, BUFLEN); + ip = (int *)&(buffer[0]); + *ip = 0; + *(ip+1) = BUFLEN - 13; + + cmd = &(buffer[8]); + cmd[0] = INQUIRY; + cmd[4] = 200; + + result = ioctl(fn, SCSI_IOCTL_SEND_COMMAND, buffer); + inqptr = buffer + IOCTL_HEADER_LENGTH; + } + if (result) { + close(fn); + sprintf(buffer, + "The SCSI INQUIRY for device '%s' failed (power off?)", + tname); + perror(buffer); + return FALSE; + } } - memcpy(company, buffer + IOCTL_HEADER_LENGTH + 8, 8); + memcpy(company, inqptr + 8, 8); for (i=8; i > 0 && company[i-1] == ' '; i--) ; company[i] = '\0'; - memcpy(product, buffer + IOCTL_HEADER_LENGTH + 16, 16); + memcpy(product, inqptr + 16, 16); for (i=16; i > 0 && product[i-1] == ' '; i--) ; product[i] = '\0'; - memcpy(rev, buffer + IOCTL_HEADER_LENGTH + 32, 4); + memcpy(rev, inqptr + 32, 4); for (i=4; i > 0 && rev[i-1] == ' '; i--) ; rev[i] = '\0';