Commit 7081dc75 authored by Kai Mäkisara's avatar Kai Mäkisara Committed by Martin K. Petersen
Browse files

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: default avatarKai Mäkisara <Kai.Makisara@kolumbus.fi>
Link: https://lore.kernel.org/r/20250120194925.44432-2-Kai.Makisara@kolumbus.fi


Reviewed-by: default avatarJohn Meneghini <jmeneghi@redhat.com>
Tested-by: default avatarJohn Meneghini <jmeneghi@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2014c95a
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -952,7 +952,6 @@ static void reset_state(struct scsi_tape *STp)
		STp->partition = find_partition(STp);
		if (STp->partition < 0)
			STp->partition = 0;
		STp->new_partition = STp->partition;
	}
}

@@ -2930,14 +2929,17 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
		if (cmd_in == MTSETDENSITY) {
			(STp->buffer)->b_data[4] = arg;
			STp->density_changed = 1;	/* At least we tried ;-) */
			STp->changed_density = arg;
		} else if (cmd_in == SET_DENS_AND_BLK)
			(STp->buffer)->b_data[4] = arg >> 24;
		else
			(STp->buffer)->b_data[4] = STp->density;
		if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
			ltmp = arg & MT_ST_BLKSIZE_MASK;
			if (cmd_in == MTSETBLK)
			if (cmd_in == MTSETBLK) {
				STp->blksize_changed = 1; /* At least we tried ;-) */
				STp->changed_blksize = arg;
			}
		} else
			ltmp = STp->block_size;
		(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)
				retval = (-EIO);
				goto out;
			}
			reset_state(STp);
			reset_state(STp); /* Clears pos_unknown */
			/* remove this when the midlevel properly clears was_reset */
			STp->device->was_reset = 0;

			/* Fix the device settings after reset, ignore errors */
			if (mtc.mt_op == MTREW || mtc.mt_op == MTSEEK ||
				mtc.mt_op == MTEOM) {
				if (STp->can_partitions) {
					/* STp->new_partition contains the
					 *  latest partition set
					 */
					STp->partition = 0;
					switch_partition(STp);
				}
				if (STp->density_changed)
					st_int_ioctl(STp, MTSETDENSITY, STp->changed_density);
				if (STp->blksize_changed)
					st_int_ioctl(STp, MTSETBLK, STp->changed_blksize);
			}
		}

		if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
+2 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ struct scsi_tape {
	unsigned char compression_changed;
	unsigned char drv_buffer;
	unsigned char density;
	unsigned char changed_density;
	unsigned char door_locked;
	unsigned char autorew_dev;   /* auto-rewind device */
	unsigned char rew_at_close;  /* rewind necessary at close */
@@ -172,6 +173,7 @@ struct scsi_tape {
	unsigned char cleaning_req;  /* cleaning requested? */
	unsigned char first_tur;     /* first TEST UNIT READY */
	int block_size;
	int changed_blksize;
	int min_block;
	int max_block;
	int recover_count;     /* From tape opening */