Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 89655
b: refs/heads/master
c: 40f6b36
h: refs/heads/master
i:
  89653: b8f77bb
  89651: 3702fbd
  89647: 0aa792c
v: v3
  • Loading branch information
Kai Makisara authored and James Bottomley committed Apr 7, 2008
1 parent 7444d7b commit 66d187f
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d35055a0f2637f29f95001a67b464fe833b09ebc
refs/heads/master: 40f6b36c6243462fb95d0343237331c423494b03
7 changes: 6 additions & 1 deletion trunk/Documentation/scsi/st.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver.
The driver is currently maintained by Kai Mäkisara (email
Kai.Makisara@kolumbus.fi)

Last modified: Mon Mar 7 21:14:44 2005 by kai.makisara
Last modified: Thu Feb 21 21:54:16 2008 by kai.makisara


BASICS
Expand Down Expand Up @@ -372,6 +372,11 @@ MTSETDRVBUFFER
MT_ST_SYSV sets the SYSV semantics (mode)
MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
the command to finish) for some commands (e.g., rewind)
MT_ST_SILI enables setting the SILI bit in SCSI commands when
reading in variable block mode to enhance performance when
reading blocks shorter than the byte count; set this only
if you are sure that the drive supports SILI and the HBA
correctly returns transfer residuals
MT_ST_DEBUGGING debugging (global; debugging must be
compiled into the driver)
MT_ST_SETBOOLEANS
Expand Down
40 changes: 36 additions & 4 deletions trunk/drivers/scsi/st.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/

static const char *verstr = "20080221";
static const char *verstr = "20080224";

#include <linux/module.h>

Expand Down Expand Up @@ -183,6 +183,7 @@ static int modes_defined;

static struct st_buffer *new_tape_buffer(int, int, int);
static int enlarge_buffer(struct st_buffer *, int, int);
static void clear_buffer(struct st_buffer *);
static void normalize_buffer(struct st_buffer *);
static int append_to_buffer(const char __user *, struct st_buffer *, int);
static int from_buffer(struct st_buffer *, char __user *, int);
Expand Down Expand Up @@ -442,6 +443,7 @@ static void st_sleep_done(void *data, char *sense, int result, int resid)

memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
(STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
(STp->buffer)->cmdstat.residual = resid;
DEB( STp->write_pending = 0; )

if (SRpnt->waiting)
Expand Down Expand Up @@ -1159,6 +1161,7 @@ static int st_open(struct inode *inode, struct file *filp)
goto err_out;
}

(STp->buffer)->cleared = 0;
(STp->buffer)->writing = 0;
(STp->buffer)->syscall_result = 0;

Expand Down Expand Up @@ -1432,8 +1435,14 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
if (STp->block_size)
bufsize = STp->block_size > st_fixed_buffer_size ?
STp->block_size : st_fixed_buffer_size;
else
else {
bufsize = count;
/* Make sure that data from previous user is not leaked even if
HBA does not return correct residual */
if (is_read && STp->sili && !STbp->cleared)
clear_buffer(STbp);
}

if (bufsize > STbp->buffer_size &&
!enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
Expand Down Expand Up @@ -1783,6 +1792,8 @@ static long read_tape(struct scsi_tape *STp, long count,
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = READ_6;
cmd[1] = (STp->block_size != 0);
if (!cmd[1] && STp->sili)
cmd[1] |= 2;
cmd[2] = blks >> 16;
cmd[3] = blks >> 8;
cmd[4] = blks;
Expand Down Expand Up @@ -1911,8 +1922,11 @@ static long read_tape(struct scsi_tape *STp, long count,

}
/* End of error handling */
else /* Read successful */
else { /* Read successful */
STbp->buffer_bytes = bytes;
if (STp->sili) /* In fixed block mode residual is always zero here */
STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
}

if (STps->drv_block >= 0) {
if (STp->block_size == 0)
Expand Down Expand Up @@ -2090,7 +2104,8 @@ static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char
name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
STp->scsi2_logical);
printk(KERN_INFO
"%s: sysv: %d nowait: %d\n", name, STm->sysv, STp->immediate);
"%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
STp->sili);
printk(KERN_INFO "%s: debugging: %d\n",
name, debugging);
}
Expand Down Expand Up @@ -2133,6 +2148,7 @@ static int st_set_options(struct scsi_tape *STp, long options)
STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
STp->immediate = (options & MT_ST_NOWAIT) != 0;
STm->sysv = (options & MT_ST_SYSV) != 0;
STp->sili = (options & MT_ST_SILI) != 0;
DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
st_log_options(STp, STm, name); )
} else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
Expand Down Expand Up @@ -2164,6 +2180,8 @@ static int st_set_options(struct scsi_tape *STp, long options)
STp->immediate = value;
if ((options & MT_ST_SYSV) != 0)
STm->sysv = value;
if ((options & MT_ST_SILI) != 0)
STp->sili = value;
DEB(
if ((options & MT_ST_DEBUGGING) != 0)
debugging = value;
Expand Down Expand Up @@ -3655,6 +3673,8 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
STbuffer->frp_segs += 1;
got += b_size;
STbuffer->buffer_size = got;
if (STbuffer->cleared)
memset(page_address(STbuffer->frp[segs].page), 0, b_size);
segs++;
}
STbuffer->b_data = page_address(STbuffer->frp[0].page);
Expand All @@ -3663,6 +3683,17 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
}


/* Make sure that no data from previous user is in the internal buffer */
static void clear_buffer(struct st_buffer * st_bp)
{
int i;

for (i=0; i < st_bp->frp_segs; i++)
memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
st_bp->cleared = 1;
}


/* Release the extra buffer */
static void normalize_buffer(struct st_buffer * STbuffer)
{
Expand Down Expand Up @@ -3987,6 +4018,7 @@ static int st_probe(struct device *dev)
tpnt->two_fm = ST_TWO_FM;
tpnt->fast_mteom = ST_FAST_MTEOM;
tpnt->scsi2_logical = ST_SCSI2LOGICAL;
tpnt->sili = ST_SILI;
tpnt->immediate = ST_NOWAIT;
tpnt->default_drvbuffer = 0xff; /* No forced buffering */
tpnt->partition = 0;
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/scsi/st.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct st_cmdstatus {
int midlevel_result;
struct scsi_sense_hdr sense_hdr;
int have_sense;
int residual;
u64 uremainder64;
u8 flags;
u8 remainder_valid;
Expand All @@ -34,6 +35,7 @@ struct st_request {
struct st_buffer {
unsigned char dma; /* DMA-able buffer */
unsigned char do_dio; /* direct i/o set up? */
unsigned char cleared; /* internal buffer cleared after open? */
int buffer_size;
int buffer_blocks;
int buffer_bytes;
Expand Down Expand Up @@ -122,6 +124,7 @@ struct scsi_tape {
unsigned char try_dio_now; /* try direct i/o before next close? */
unsigned char c_algo; /* compression algorithm */
unsigned char pos_unknown; /* after reset position unknown */
unsigned char sili; /* use SILI when reading in variable b mode */
int tape_type;
int long_timeout; /* timeout for commands known to take long time */

Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/scsi/st_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Copyright 1995-2003 Kai Makisara.
Last modified: Mon Apr 7 22:49:18 2003 by makisara
Last modified: Thu Feb 21 21:47:07 2008 by kai.makisara
*/

#ifndef _ST_OPTIONS_H
Expand Down Expand Up @@ -94,6 +94,10 @@
The default is BSD semantics. */
#define ST_SYSV 0

/* If ST_SILI is non-zero, the SILI bit is set when reading in variable block
mode and the block size is determined using the residual returned by the HBA. */
#define ST_SILI 0

/* Time to wait for the drive to become ready if blocking open */
#define ST_BLOCK_SECONDS 120

Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/mtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ struct mtpos {
#define MT_ST_SCSI2LOGICAL 0x800
#define MT_ST_SYSV 0x1000
#define MT_ST_NOWAIT 0x2000
#define MT_ST_SILI 0x4000

/* The mode parameters to be controlled. Parameter chosen with bits 20-28 */
#define MT_ST_CLEAR_DEFAULT 0xfffff
Expand Down

0 comments on commit 66d187f

Please sign in to comment.