Commit 40f6b36c6243462fb95d0343237331c423494b03

Authored by Kai Makisara
Committed by James Bottomley
1 parent d35055a0f2

[SCSI] st: add option to use SILI in variable block reads

Add new option MT_ST_SILI to enable setting the SILI bit in reads in variable
block mode. If SILI is set, reading a block shorter than the byte count does
not result in CHECK CONDITION. The length of the block is determined using the
residual count from the HBA. Avoiding the REQUEST SENSE command for every
block speeds up some real applications considerably.

Signed-off-by: Kai Makisara <kai.makisara@kolumbus.fi>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

Showing 5 changed files with 51 additions and 6 deletions Side-by-side Diff

Documentation/scsi/st.txt
... ... @@ -2,7 +2,7 @@
2 2 The driver is currently maintained by Kai Mäkisara (email
3 3 Kai.Makisara@kolumbus.fi)
4 4  
5   -Last modified: Mon Mar 7 21:14:44 2005 by kai.makisara
  5 +Last modified: Thu Feb 21 21:54:16 2008 by kai.makisara
6 6  
7 7  
8 8 BASICS
... ... @@ -372,6 +372,11 @@
372 372 MT_ST_SYSV sets the SYSV semantics (mode)
373 373 MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
374 374 the command to finish) for some commands (e.g., rewind)
  375 + MT_ST_SILI enables setting the SILI bit in SCSI commands when
  376 + reading in variable block mode to enhance performance when
  377 + reading blocks shorter than the byte count; set this only
  378 + if you are sure that the drive supports SILI and the HBA
  379 + correctly returns transfer residuals
375 380 MT_ST_DEBUGGING debugging (global; debugging must be
376 381 compiled into the driver)
377 382 MT_ST_SETBOOLEANS
... ... @@ -17,7 +17,7 @@
17 17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 18 */
19 19  
20   -static const char *verstr = "20080221";
  20 +static const char *verstr = "20080224";
21 21  
22 22 #include <linux/module.h>
23 23  
... ... @@ -183,6 +183,7 @@
183 183  
184 184 static struct st_buffer *new_tape_buffer(int, int, int);
185 185 static int enlarge_buffer(struct st_buffer *, int, int);
  186 +static void clear_buffer(struct st_buffer *);
186 187 static void normalize_buffer(struct st_buffer *);
187 188 static int append_to_buffer(const char __user *, struct st_buffer *, int);
188 189 static int from_buffer(struct st_buffer *, char __user *, int);
... ... @@ -442,6 +443,7 @@
442 443  
443 444 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
444 445 (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
  446 + (STp->buffer)->cmdstat.residual = resid;
445 447 DEB( STp->write_pending = 0; )
446 448  
447 449 if (SRpnt->waiting)
... ... @@ -1159,6 +1161,7 @@
1159 1161 goto err_out;
1160 1162 }
1161 1163  
  1164 + (STp->buffer)->cleared = 0;
1162 1165 (STp->buffer)->writing = 0;
1163 1166 (STp->buffer)->syscall_result = 0;
1164 1167  
1165 1168  
... ... @@ -1432,8 +1435,14 @@
1432 1435 if (STp->block_size)
1433 1436 bufsize = STp->block_size > st_fixed_buffer_size ?
1434 1437 STp->block_size : st_fixed_buffer_size;
1435   - else
  1438 + else {
1436 1439 bufsize = count;
  1440 + /* Make sure that data from previous user is not leaked even if
  1441 + HBA does not return correct residual */
  1442 + if (is_read && STp->sili && !STbp->cleared)
  1443 + clear_buffer(STbp);
  1444 + }
  1445 +
1437 1446 if (bufsize > STbp->buffer_size &&
1438 1447 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1439 1448 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
... ... @@ -1783,6 +1792,8 @@
1783 1792 memset(cmd, 0, MAX_COMMAND_SIZE);
1784 1793 cmd[0] = READ_6;
1785 1794 cmd[1] = (STp->block_size != 0);
  1795 + if (!cmd[1] && STp->sili)
  1796 + cmd[1] |= 2;
1786 1797 cmd[2] = blks >> 16;
1787 1798 cmd[3] = blks >> 8;
1788 1799 cmd[4] = blks;
1789 1800  
... ... @@ -1911,8 +1922,11 @@
1911 1922  
1912 1923 }
1913 1924 /* End of error handling */
1914   - else /* Read successful */
  1925 + else { /* Read successful */
1915 1926 STbp->buffer_bytes = bytes;
  1927 + if (STp->sili) /* In fixed block mode residual is always zero here */
  1928 + STbp->buffer_bytes -= STp->buffer->cmdstat.residual;
  1929 + }
1916 1930  
1917 1931 if (STps->drv_block >= 0) {
1918 1932 if (STp->block_size == 0)
... ... @@ -2090,7 +2104,8 @@
2090 2104 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2091 2105 STp->scsi2_logical);
2092 2106 printk(KERN_INFO
2093   - "%s: sysv: %d nowait: %d\n", name, STm->sysv, STp->immediate);
  2107 + "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate,
  2108 + STp->sili);
2094 2109 printk(KERN_INFO "%s: debugging: %d\n",
2095 2110 name, debugging);
2096 2111 }
... ... @@ -2133,6 +2148,7 @@
2133 2148 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2134 2149 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2135 2150 STm->sysv = (options & MT_ST_SYSV) != 0;
  2151 + STp->sili = (options & MT_ST_SILI) != 0;
2136 2152 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2137 2153 st_log_options(STp, STm, name); )
2138 2154 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
... ... @@ -2164,6 +2180,8 @@
2164 2180 STp->immediate = value;
2165 2181 if ((options & MT_ST_SYSV) != 0)
2166 2182 STm->sysv = value;
  2183 + if ((options & MT_ST_SILI) != 0)
  2184 + STp->sili = value;
2167 2185 DEB(
2168 2186 if ((options & MT_ST_DEBUGGING) != 0)
2169 2187 debugging = value;
... ... @@ -3655,6 +3673,8 @@
3655 3673 STbuffer->frp_segs += 1;
3656 3674 got += b_size;
3657 3675 STbuffer->buffer_size = got;
  3676 + if (STbuffer->cleared)
  3677 + memset(page_address(STbuffer->frp[segs].page), 0, b_size);
3658 3678 segs++;
3659 3679 }
3660 3680 STbuffer->b_data = page_address(STbuffer->frp[0].page);
... ... @@ -3663,6 +3683,17 @@
3663 3683 }
3664 3684  
3665 3685  
  3686 +/* Make sure that no data from previous user is in the internal buffer */
  3687 +static void clear_buffer(struct st_buffer * st_bp)
  3688 +{
  3689 + int i;
  3690 +
  3691 + for (i=0; i < st_bp->frp_segs; i++)
  3692 + memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
  3693 + st_bp->cleared = 1;
  3694 +}
  3695 +
  3696 +
3666 3697 /* Release the extra buffer */
3667 3698 static void normalize_buffer(struct st_buffer * STbuffer)
3668 3699 {
... ... @@ -3987,6 +4018,7 @@
3987 4018 tpnt->two_fm = ST_TWO_FM;
3988 4019 tpnt->fast_mteom = ST_FAST_MTEOM;
3989 4020 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
  4021 + tpnt->sili = ST_SILI;
3990 4022 tpnt->immediate = ST_NOWAIT;
3991 4023 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
3992 4024 tpnt->partition = 0;
... ... @@ -12,6 +12,7 @@
12 12 int midlevel_result;
13 13 struct scsi_sense_hdr sense_hdr;
14 14 int have_sense;
  15 + int residual;
15 16 u64 uremainder64;
16 17 u8 flags;
17 18 u8 remainder_valid;
... ... @@ -34,6 +35,7 @@
34 35 struct st_buffer {
35 36 unsigned char dma; /* DMA-able buffer */
36 37 unsigned char do_dio; /* direct i/o set up? */
  38 + unsigned char cleared; /* internal buffer cleared after open? */
37 39 int buffer_size;
38 40 int buffer_blocks;
39 41 int buffer_bytes;
... ... @@ -122,6 +124,7 @@
122 124 unsigned char try_dio_now; /* try direct i/o before next close? */
123 125 unsigned char c_algo; /* compression algorithm */
124 126 unsigned char pos_unknown; /* after reset position unknown */
  127 + unsigned char sili; /* use SILI when reading in variable b mode */
125 128 int tape_type;
126 129 int long_timeout; /* timeout for commands known to take long time */
127 130  
drivers/scsi/st_options.h
... ... @@ -3,7 +3,7 @@
3 3  
4 4 Copyright 1995-2003 Kai Makisara.
5 5  
6   - Last modified: Mon Apr 7 22:49:18 2003 by makisara
  6 + Last modified: Thu Feb 21 21:47:07 2008 by kai.makisara
7 7 */
8 8  
9 9 #ifndef _ST_OPTIONS_H
... ... @@ -93,6 +93,10 @@
93 93 /* If ST_SYSV is non-zero, the tape behaves according to the SYS V semantics.
94 94 The default is BSD semantics. */
95 95 #define ST_SYSV 0
  96 +
  97 +/* If ST_SILI is non-zero, the SILI bit is set when reading in variable block
  98 + mode and the block size is determined using the residual returned by the HBA. */
  99 +#define ST_SILI 0
96 100  
97 101 /* Time to wait for the drive to become ready if blocking open */
98 102 #define ST_BLOCK_SECONDS 120
include/linux/mtio.h
... ... @@ -192,6 +192,7 @@
192 192 #define MT_ST_SCSI2LOGICAL 0x800
193 193 #define MT_ST_SYSV 0x1000
194 194 #define MT_ST_NOWAIT 0x2000
  195 +#define MT_ST_SILI 0x4000
195 196  
196 197 /* The mode parameters to be controlled. Parameter chosen with bits 20-28 */
197 198 #define MT_ST_CLEAR_DEFAULT 0xfffff