Skip to content

Commit 7081dc7

Browse files
kmakisaramartinkpetersen
authored andcommitted
scsi: st: Restore some drive settings after reset
Some of the allowed operations put the tape into a known position to continue operation assuming only the tape position has changed. But reset sets partition, density and block size to drive default values. These should be restored to the values before reset. Normally the current block size and density are stored by the drive. If the settings have been changed, the changed values have to be saved by the driver across reset. Signed-off-by: Kai Mäkisara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: John Meneghini <[email protected]> Tested-by: John Meneghini <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 2014c95 commit 7081dc7

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

drivers/scsi/st.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,6 @@ static void reset_state(struct scsi_tape *STp)
952952
STp->partition = find_partition(STp);
953953
if (STp->partition < 0)
954954
STp->partition = 0;
955-
STp->new_partition = STp->partition;
956955
}
957956
}
958957

@@ -2930,14 +2929,17 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
29302929
if (cmd_in == MTSETDENSITY) {
29312930
(STp->buffer)->b_data[4] = arg;
29322931
STp->density_changed = 1; /* At least we tried ;-) */
2932+
STp->changed_density = arg;
29332933
} else if (cmd_in == SET_DENS_AND_BLK)
29342934
(STp->buffer)->b_data[4] = arg >> 24;
29352935
else
29362936
(STp->buffer)->b_data[4] = STp->density;
29372937
if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
29382938
ltmp = arg & MT_ST_BLKSIZE_MASK;
2939-
if (cmd_in == MTSETBLK)
2939+
if (cmd_in == MTSETBLK) {
29402940
STp->blksize_changed = 1; /* At least we tried ;-) */
2941+
STp->changed_blksize = arg;
2942+
}
29412943
} else
29422944
ltmp = STp->block_size;
29432945
(STp->buffer)->b_data[9] = (ltmp >> 16);
@@ -3636,9 +3638,25 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
36363638
retval = (-EIO);
36373639
goto out;
36383640
}
3639-
reset_state(STp);
3641+
reset_state(STp); /* Clears pos_unknown */
36403642
/* remove this when the midlevel properly clears was_reset */
36413643
STp->device->was_reset = 0;
3644+
3645+
/* Fix the device settings after reset, ignore errors */
3646+
if (mtc.mt_op == MTREW || mtc.mt_op == MTSEEK ||
3647+
mtc.mt_op == MTEOM) {
3648+
if (STp->can_partitions) {
3649+
/* STp->new_partition contains the
3650+
* latest partition set
3651+
*/
3652+
STp->partition = 0;
3653+
switch_partition(STp);
3654+
}
3655+
if (STp->density_changed)
3656+
st_int_ioctl(STp, MTSETDENSITY, STp->changed_density);
3657+
if (STp->blksize_changed)
3658+
st_int_ioctl(STp, MTSETBLK, STp->changed_blksize);
3659+
}
36423660
}
36433661

36443662
if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&

drivers/scsi/st.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,15 @@ struct scsi_tape {
165165
unsigned char compression_changed;
166166
unsigned char drv_buffer;
167167
unsigned char density;
168+
unsigned char changed_density;
168169
unsigned char door_locked;
169170
unsigned char autorew_dev; /* auto-rewind device */
170171
unsigned char rew_at_close; /* rewind necessary at close */
171172
unsigned char inited;
172173
unsigned char cleaning_req; /* cleaning requested? */
173174
unsigned char first_tur; /* first TEST UNIT READY */
174175
int block_size;
176+
int changed_blksize;
175177
int min_block;
176178
int max_block;
177179
int recover_count; /* From tape opening */

0 commit comments

Comments
 (0)