The patch at the end of this message applies to 2.6.11 + st descriptor sense patch + st auto eof patch (i.e., st patches currently in scsi-misc-2.6). The patch fixes the following problems:
- the sense descriptor is cleared before filling - BSF and BSFM are added to the commands causing automatic writing of filemark if the previous operation was write (tar expects this) - the block number is set to unknown (-1) if spacing forward ends at BLANK CHECK - debugging printout of spacing counts fixed to work also with 64-bit systems Signed-off-by: Kai Makisara <[EMAIL PROTECTED]> --- linux-2.6.11-k1/drivers/scsi/st.c 2005-03-07 19:38:45.000000000 +0200 +++ linux-2.6.11-k2/drivers/scsi/st.c 2005-03-07 21:59:24.000000000 +0200 @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch <[EMAIL PROTECTED]> Devfs support */ -static char *verstr = "20050213"; +static char *verstr = "20050307"; #include <linux/module.h> @@ -268,6 +268,7 @@ static void st_analyze_sense(struct scsi const u8 *ucp; const u8 *sense = SRpnt->sr_sense_buffer; + memset(s, 0, sizeof(struct st_cmdstatus)); s->have_sense = scsi_request_normalize_sense(SRpnt, &s->sense_hdr); if (s->have_sense) { @@ -287,8 +288,6 @@ static void st_analyze_sense(struct scsi ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4); s->flags = ucp ? (ucp[3] & 0xe0) : 0; break; - default: - s->flags = 0; } } } @@ -306,7 +305,7 @@ static int st_chk_result(struct scsi_tap if (!result) return 0; - cmdstatp = &STp->buffer->cmdstat; + cmdstatp = &STp->buffer->cmdstat; st_analyze_sense(STp->buffer->last_SRpnt, cmdstatp); if (cmdstatp->have_sense) @@ -2407,6 +2406,22 @@ static int do_load_unload(struct scsi_ta return retval; } +#if DEBUG +#define ST_DEB_FORWARD 0 +#define ST_DEB_BACKWARD 1 +static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd) +{ + s32 sc; + + sc = cmd[2] & 0x80 ? 0xff000000 : 0; + sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4]; + if (direction) + sc = -sc; + printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name, + direction ? "backward" : "forward", sc, units); +} +#endif + /* Internal ioctl function */ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned long arg) @@ -2445,8 +2460,7 @@ static int st_int_ioctl(struct scsi_tape cmd[2] = (arg >> 16); cmd[3] = (arg >> 8); cmd[4] = arg; - DEBC(printk(ST_DEB_MSG "%s: Spacing tape forward over %d filemarks.\n", - name, cmd[2] * 65536 + cmd[3] * 256 + cmd[4])); + DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);) if (fileno >= 0) fileno += arg; blkno = 0; @@ -2461,14 +2475,7 @@ static int st_int_ioctl(struct scsi_tape cmd[2] = (ltmp >> 16); cmd[3] = (ltmp >> 8); cmd[4] = ltmp; - DEBC( - if (cmd[2] & 0x80) - ltmp = 0xff000000; - ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4]; - printk(ST_DEB_MSG - "%s: Spacing tape backward over %ld filemarks.\n", - name, (-ltmp)); - ) + DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);) if (fileno >= 0) fileno -= arg; blkno = (-1); /* We can't know the block number */ @@ -2480,8 +2487,7 @@ static int st_int_ioctl(struct scsi_tape cmd[2] = (arg >> 16); cmd[3] = (arg >> 8); cmd[4] = arg; - DEBC(printk(ST_DEB_MSG "%s: Spacing tape forward %d blocks.\n", name, - cmd[2] * 65536 + cmd[3] * 256 + cmd[4])); + DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);) if (blkno >= 0) blkno += arg; at_sm &= (arg == 0); @@ -2493,13 +2499,7 @@ static int st_int_ioctl(struct scsi_tape cmd[2] = (ltmp >> 16); cmd[3] = (ltmp >> 8); cmd[4] = ltmp; - DEBC( - if (cmd[2] & 0x80) - ltmp = 0xff000000; - ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4]; - printk(ST_DEB_MSG - "%s: Spacing tape backward %ld blocks.\n", name, (-ltmp)); - ) + DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);) if (blkno >= 0) blkno -= arg; at_sm &= (arg == 0); @@ -2510,8 +2510,7 @@ static int st_int_ioctl(struct scsi_tape cmd[2] = (arg >> 16); cmd[3] = (arg >> 8); cmd[4] = arg; - DEBC(printk(ST_DEB_MSG "%s: Spacing tape forward %d setmarks.\n", name, - cmd[2] * 65536 + cmd[3] * 256 + cmd[4])); + DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);) if (arg != 0) { blkno = fileno = (-1); at_sm = 1; @@ -2524,13 +2523,7 @@ static int st_int_ioctl(struct scsi_tape cmd[2] = (ltmp >> 16); cmd[3] = (ltmp >> 8); cmd[4] = ltmp; - DEBC( - if (cmd[2] & 0x80) - ltmp = 0xff000000; - ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4]; - printk(ST_DEB_MSG "%s: Spacing tape backward %ld setmarks.\n", - name, (-ltmp)); - ) + DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);) if (arg != 0) { blkno = fileno = (-1); at_sm = 1; @@ -2600,7 +2593,7 @@ static int st_int_ioctl(struct scsi_tape cmd[1] = 3; DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n", name)); - blkno = 0; + blkno = -1; at_sm = 0; break; case MTERASE: @@ -2761,7 +2754,7 @@ static int st_int_ioctl(struct scsi_tape STps->drv_file = fileno - undone; else STps->drv_file = fileno; - STps->drv_block = 0; + STps->drv_block = -1; STps->eof = ST_NOEOF; } else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) { if (arg > 0 && undone < 0) /* Some drives get this wrong */ @@ -3239,12 +3232,15 @@ static int st_ioctl(struct inode *inode, } if (STps->rw == ST_WRITING && (mtc.mt_op == MTREW || mtc.mt_op == MTOFFL || - mtc.mt_op == MTSEEK)) { + mtc.mt_op == MTSEEK || + mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM)) { i = st_int_ioctl(STp, MTWEOF, 1); if (i < 0) { retval = i; goto out; } + if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) + mtc.mt_count++; STps->rw = ST_IDLE; } --- linux-2.6.11-k1/Documentation/scsi/st.txt 2005-03-07 19:38:45.000000000 +0200 +++ linux-2.6.11-k2/Documentation/scsi/st.txt 2005-03-07 21:14:44.000000000 +0200 @@ -2,7 +2,7 @@ This file contains brief information abo The driver is currently maintained by Kai Mäkisara (email [EMAIL PROTECTED]) -Last modified: Sun Feb 20 22:28:27 2005 by kai.makisara +Last modified: Mon Mar 7 21:14:44 2005 by kai.makisara BASICS @@ -85,8 +85,8 @@ writing and the last operation has been optionally written. In both cases end of data is signified by returning zero bytes for two consecutive reads. -If the rewind, offline, or seek is done and previous tape operation was write, -a filemark is written before moving tape. +If rewind, offline, bsf, or seek is done and previous tape operation was +write, a filemark is written before moving tape. The compile options are defined in the file linux/drivers/scsi/st_options.h.