aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/st.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r--drivers/scsi/st.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 0a52d9d2da2c..a4361a8c6ac6 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support 17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 */ 18 */
19 19
20static const char *verstr = "20080221"; 20static const char *verstr = "20080224";
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23 23
@@ -183,6 +183,7 @@ static int modes_defined;
183 183
184static struct st_buffer *new_tape_buffer(int, int, int); 184static struct st_buffer *new_tape_buffer(int, int, int);
185static int enlarge_buffer(struct st_buffer *, int, int); 185static int enlarge_buffer(struct st_buffer *, int, int);
186static void clear_buffer(struct st_buffer *);
186static void normalize_buffer(struct st_buffer *); 187static void normalize_buffer(struct st_buffer *);
187static int append_to_buffer(const char __user *, struct st_buffer *, int); 188static int append_to_buffer(const char __user *, struct st_buffer *, int);
188static int from_buffer(struct st_buffer *, char __user *, int); 189static int from_buffer(struct st_buffer *, char __user *, int);
@@ -442,6 +443,7 @@ static void st_sleep_done(void *data, char *sense, int result, int resid)
442 443
443 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); 444 memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
444 (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; 445 (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
446 (STp->buffer)->cmdstat.residual = resid;
445 DEB( STp->write_pending = 0; ) 447 DEB( STp->write_pending = 0; )
446 448
447 if (SRpnt->waiting) 449 if (SRpnt->waiting)
@@ -1159,6 +1161,7 @@ static int st_open(struct inode *inode, struct file *filp)
1159 goto err_out; 1161 goto err_out;
1160 } 1162 }
1161 1163
1164 (STp->buffer)->cleared = 0;
1162 (STp->buffer)->writing = 0; 1165 (STp->buffer)->writing = 0;
1163 (STp->buffer)->syscall_result = 0; 1166 (STp->buffer)->syscall_result = 0;
1164 1167
@@ -1432,8 +1435,14 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
1432 if (STp->block_size) 1435 if (STp->block_size)
1433 bufsize = STp->block_size > st_fixed_buffer_size ? 1436 bufsize = STp->block_size > st_fixed_buffer_size ?
1434 STp->block_size : st_fixed_buffer_size; 1437 STp->block_size : st_fixed_buffer_size;
1435 else 1438 else {
1436 bufsize = count; 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 if (bufsize > STbp->buffer_size && 1446 if (bufsize > STbp->buffer_size &&
1438 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) { 1447 !enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
1439 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n", 1448 printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
@@ -1783,6 +1792,8 @@ static long read_tape(struct scsi_tape *STp, long count,
1783 memset(cmd, 0, MAX_COMMAND_SIZE); 1792 memset(cmd, 0, MAX_COMMAND_SIZE);
1784 cmd[0] = READ_6; 1793 cmd[0] = READ_6;
1785 cmd[1] = (STp->block_size != 0); 1794 cmd[1] = (STp->block_size != 0);
1795 if (!cmd[1] && STp->sili)
1796 cmd[1] |= 2;
1786 cmd[2] = blks >> 16; 1797 cmd[2] = blks >> 16;
1787 cmd[3] = blks >> 8; 1798 cmd[3] = blks >> 8;
1788 cmd[4] = blks; 1799 cmd[4] = blks;
@@ -1911,8 +1922,11 @@ static long read_tape(struct scsi_tape *STp, long count,
1911 1922
1912 } 1923 }
1913 /* End of error handling */ 1924 /* End of error handling */
1914 else /* Read successful */ 1925 else { /* Read successful */
1915 STbp->buffer_bytes = bytes; 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 if (STps->drv_block >= 0) { 1931 if (STps->drv_block >= 0) {
1918 if (STp->block_size == 0) 1932 if (STp->block_size == 0)
@@ -2090,7 +2104,8 @@ static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char
2090 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, 2104 name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
2091 STp->scsi2_logical); 2105 STp->scsi2_logical);
2092 printk(KERN_INFO 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 printk(KERN_INFO "%s: debugging: %d\n", 2109 printk(KERN_INFO "%s: debugging: %d\n",
2095 name, debugging); 2110 name, debugging);
2096 } 2111 }
@@ -2133,6 +2148,7 @@ static int st_set_options(struct scsi_tape *STp, long options)
2133 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; 2148 STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
2134 STp->immediate = (options & MT_ST_NOWAIT) != 0; 2149 STp->immediate = (options & MT_ST_NOWAIT) != 0;
2135 STm->sysv = (options & MT_ST_SYSV) != 0; 2150 STm->sysv = (options & MT_ST_SYSV) != 0;
2151 STp->sili = (options & MT_ST_SILI) != 0;
2136 DEB( debugging = (options & MT_ST_DEBUGGING) != 0; 2152 DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
2137 st_log_options(STp, STm, name); ) 2153 st_log_options(STp, STm, name); )
2138 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { 2154 } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
@@ -2164,6 +2180,8 @@ static int st_set_options(struct scsi_tape *STp, long options)
2164 STp->immediate = value; 2180 STp->immediate = value;
2165 if ((options & MT_ST_SYSV) != 0) 2181 if ((options & MT_ST_SYSV) != 0)
2166 STm->sysv = value; 2182 STm->sysv = value;
2183 if ((options & MT_ST_SILI) != 0)
2184 STp->sili = value;
2167 DEB( 2185 DEB(
2168 if ((options & MT_ST_DEBUGGING) != 0) 2186 if ((options & MT_ST_DEBUGGING) != 0)
2169 debugging = value; 2187 debugging = value;
@@ -3655,6 +3673,8 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
3655 STbuffer->frp_segs += 1; 3673 STbuffer->frp_segs += 1;
3656 got += b_size; 3674 got += b_size;
3657 STbuffer->buffer_size = got; 3675 STbuffer->buffer_size = got;
3676 if (STbuffer->cleared)
3677 memset(page_address(STbuffer->frp[segs].page), 0, b_size);
3658 segs++; 3678 segs++;
3659 } 3679 }
3660 STbuffer->b_data = page_address(STbuffer->frp[0].page); 3680 STbuffer->b_data = page_address(STbuffer->frp[0].page);
@@ -3663,6 +3683,17 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
3663} 3683}
3664 3684
3665 3685
3686/* Make sure that no data from previous user is in the internal buffer */
3687static 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/* Release the extra buffer */ 3697/* Release the extra buffer */
3667static void normalize_buffer(struct st_buffer * STbuffer) 3698static void normalize_buffer(struct st_buffer * STbuffer)
3668{ 3699{
@@ -3987,6 +4018,7 @@ static int st_probe(struct device *dev)
3987 tpnt->two_fm = ST_TWO_FM; 4018 tpnt->two_fm = ST_TWO_FM;
3988 tpnt->fast_mteom = ST_FAST_MTEOM; 4019 tpnt->fast_mteom = ST_FAST_MTEOM;
3989 tpnt->scsi2_logical = ST_SCSI2LOGICAL; 4020 tpnt->scsi2_logical = ST_SCSI2LOGICAL;
4021 tpnt->sili = ST_SILI;
3990 tpnt->immediate = ST_NOWAIT; 4022 tpnt->immediate = ST_NOWAIT;
3991 tpnt->default_drvbuffer = 0xff; /* No forced buffering */ 4023 tpnt->default_drvbuffer = 0xff; /* No forced buffering */
3992 tpnt->partition = 0; 4024 tpnt->partition = 0;