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.c89
1 files changed, 82 insertions, 7 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 0a52d9d2da2c..df83bea2c620 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)
@@ -626,7 +628,7 @@ static int cross_eof(struct scsi_tape * STp, int forward)
626 628
627 629
628/* Flush the write buffer (never need to write if variable blocksize). */ 630/* Flush the write buffer (never need to write if variable blocksize). */
629static int flush_write_buffer(struct scsi_tape * STp) 631static int st_flush_write_buffer(struct scsi_tape * STp)
630{ 632{
631 int offset, transfer, blks; 633 int offset, transfer, blks;
632 int result; 634 int result;
@@ -717,7 +719,7 @@ static int flush_buffer(struct scsi_tape *STp, int seek_next)
717 return 0; 719 return 0;
718 STps = &(STp->ps[STp->partition]); 720 STps = &(STp->ps[STp->partition]);
719 if (STps->rw == ST_WRITING) /* Writing */ 721 if (STps->rw == ST_WRITING) /* Writing */
720 return flush_write_buffer(STp); 722 return st_flush_write_buffer(STp);
721 723
722 if (STp->block_size == 0) 724 if (STp->block_size == 0)
723 return 0; 725 return 0;
@@ -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
@@ -1211,7 +1214,7 @@ static int st_flush(struct file *filp, fl_owner_t id)
1211 return 0; 1214 return 0;
1212 1215
1213 if (STps->rw == ST_WRITING && !STp->pos_unknown) { 1216 if (STps->rw == ST_WRITING && !STp->pos_unknown) {
1214 result = flush_write_buffer(STp); 1217 result = st_flush_write_buffer(STp);
1215 if (result != 0 && result != (-ENOSPC)) 1218 if (result != 0 && result != (-ENOSPC))
1216 goto out; 1219 goto out;
1217 } 1220 }
@@ -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;
@@ -4333,6 +4365,46 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf)
4333 4365
4334CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); 4366CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
4335 4367
4368static ssize_t st_options_show(struct class_device *class_dev, char *buf)
4369{
4370 struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev);
4371 struct scsi_tape *STp;
4372 int i, j, options;
4373 ssize_t l = 0;
4374
4375 for (i=0; i < st_dev_max; i++) {
4376 for (j=0; j < ST_NBR_MODES; j++)
4377 if (&scsi_tapes[i]->modes[j] == STm)
4378 break;
4379 if (j < ST_NBR_MODES)
4380 break;
4381 }
4382 if (i == st_dev_max)
4383 return 0; /* should never happen */
4384
4385 STp = scsi_tapes[i];
4386
4387 options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
4388 options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
4389 options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
4390 DEB( options |= debugging ? MT_ST_DEBUGGING : 0 );
4391 options |= STp->two_fm ? MT_ST_TWO_FM : 0;
4392 options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0;
4393 options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0;
4394 options |= STp->can_bsr ? MT_ST_CAN_BSR : 0;
4395 options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0;
4396 options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0;
4397 options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0;
4398 options |= STm->sysv ? MT_ST_SYSV : 0;
4399 options |= STp->immediate ? MT_ST_NOWAIT : 0;
4400 options |= STp->sili ? MT_ST_SILI : 0;
4401
4402 l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options);
4403 return l;
4404}
4405
4406CLASS_DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
4407
4336static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) 4408static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4337{ 4409{
4338 int i, rew, error; 4410 int i, rew, error;
@@ -4370,6 +4442,9 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4370 error = class_device_create_file(st_class_member, 4442 error = class_device_create_file(st_class_member,
4371 &class_device_attr_default_compression); 4443 &class_device_attr_default_compression);
4372 if (error) goto out; 4444 if (error) goto out;
4445 error = class_device_create_file(st_class_member,
4446 &class_device_attr_options);
4447 if (error) goto out;
4373 4448
4374 if (mode == 0 && rew == 0) { 4449 if (mode == 0 && rew == 0) {
4375 error = sysfs_create_link(&STp->device->sdev_gendev.kobj, 4450 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,