diff mbox series

scsi: st: Regression fix: Don't set pos_unknown just after device recognition

Message ID 20241216113755.30415-1-Kai.Makisara@kolumbus.fi (mailing list archive)
State New
Headers show
Series scsi: st: Regression fix: Don't set pos_unknown just after device recognition | expand

Commit Message

Kai Mäkisara (Kolumbus) Dec. 16, 2024, 11:37 a.m. UTC
Commit 9604eea5bd3a ("scsi: st: Add third party poweron reset handling")
in v6.6 added new code to handle the Power On/Reset Unit Attention
(POR UA) sense data. This was in addition to the existing method. When
this Unit Attention is received, the driver blocks attempts to read,
write and some other operations because the reset may have rewinded
the tape. Because of the added code, also the initial POR UA resulted
in blocking operations, including those that are used to set the driver
options after the device is recognized. Also, reading and writing are
refused, whereas they succeeded before this commit.

This patch adds code to not set pos_unknown to block operations if the
POR UA is received from the first test_ready() call after the st device
has been created. This restores the behavior before v6.6.

Signed-off-by: Kai Mäkisara <Kai.Makisara@kolumbus.fi>
Fixes: 9604eea5bd3a ("scsi: st: Add third party poweron reset handling")
Closes: https://lore.kernel.org/linux-scsi/2201CF73-4795-4D3B-9A79-6EE5215CF58D@kolumbus.fi/
CC: stable@vger.kernel.org
---
 drivers/scsi/st.c | 6 ++++++
 drivers/scsi/st.h | 1 +
 2 files changed, 7 insertions(+)

Comments

Bart Van Assche Dec. 16, 2024, 5:18 p.m. UTC | #1
On 12/16/24 3:37 AM, Kai Mäkisara wrote:
> diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
> index 7a68eaba7e81..1aaaf5369a40 100644
> --- a/drivers/scsi/st.h
> +++ b/drivers/scsi/st.h
> @@ -170,6 +170,7 @@ struct scsi_tape {
>   	unsigned char rew_at_close;  /* rewind necessary at close */
>   	unsigned char inited;
>   	unsigned char cleaning_req;  /* cleaning requested? */
> +	unsigned char first_tur;     /* first TEST UNIT READY */
>   	int block_size;
>   	int min_block;
>   	int max_block;

Why 'unsigned char' instead of 'bool'?

Should perhaps all 'unsigned char' occurrences in struct scsi_tape be
changed into 'bool'? I'm not aware of any other Linux kernel code that
uses the type 'unsigned char' for boolean values.

Thanks,

Bart.
Kai Mäkisara (Kolumbus) Dec. 16, 2024, 6:08 p.m. UTC | #2
On 16. Dec 2024, at 19.18, Bart Van Assche <bvanassche@acm.org> wrote:
> 
> On 12/16/24 3:37 AM, Kai Mäkisara wrote:
>> diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
>> index 7a68eaba7e81..1aaaf5369a40 100644
>> --- a/drivers/scsi/st.h
>> +++ b/drivers/scsi/st.h
>> @@ -170,6 +170,7 @@ struct scsi_tape {
>>   unsigned char rew_at_close;  /* rewind necessary at close */
>>   unsigned char inited;
>>   unsigned char cleaning_req;  /* cleaning requested? */
>> + unsigned char first_tur;     /* first TEST UNIT READY */
>>   int block_size;
>>   int min_block;
>>   int max_block;
> 
> Why 'unsigned char' instead of 'bool'?

For historical reasons I used the same type as in the other options.
(I happen to have 1.3.30 sources from 1995. The flags in st.h are
unsigned chars there. AFAIK, the type bool was introduces in C99
in 1999.)

> Should perhaps all 'unsigned char' occurrences in struct scsi_tape be
> changed into 'bool'? I'm not aware of any other Linux kernel code that
> uses the type 'unsigned char' for boolean values.

This also came into my mind, but this is a regression fix and I tried
to keep it minimal.

A patch to change the types can be done later.

Thanks,
Kai
diff mbox series

Patch

diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index e8ef27d7ef61..ebbd50ec0cda 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -1030,6 +1030,11 @@  static int test_ready(struct scsi_tape *STp, int do_wait)
 			retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
 		break;
 	}
+	if (STp->first_tur) {
+		/* Don't set pos_unknown right after device recognition */
+		STp->pos_unknown = 0;
+		STp->first_tur = 0;
+	}
 
 	if (SRpnt != NULL)
 		st_release_request(SRpnt);
@@ -4328,6 +4333,7 @@  static int st_probe(struct device *dev)
 	blk_queue_rq_timeout(tpnt->device->request_queue, ST_TIMEOUT);
 	tpnt->long_timeout = ST_LONG_TIMEOUT;
 	tpnt->try_dio = try_direct_io;
+	tpnt->first_tur = 1;
 
 	for (i = 0; i < ST_NBR_MODES; i++) {
 		STm = &(tpnt->modes[i]);
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 7a68eaba7e81..1aaaf5369a40 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -170,6 +170,7 @@  struct scsi_tape {
 	unsigned char rew_at_close;  /* rewind necessary at close */
 	unsigned char inited;
 	unsigned char cleaning_req;  /* cleaning requested? */
+	unsigned char first_tur;     /* first TEST UNIT READY */
 	int block_size;
 	int min_block;
 	int max_block;