Skip to content

Commit 341128d

Browse files
kmakisaramartinkpetersen
authored andcommitted
scsi: st: Modify st.c to use the new scsi_error counters
Compare the stored values of por_ctr and new_media_ctr against the values in the device struct. In case of mismatch, the Unit Attention corresponding to the counter has happened. This is a safeguard against another ULD catching the Unit Attention sense data. Macros scsi_get_ua_new_media_ctr and scsi_get_ua_por_ctr are added to read the current values of the counters. Signed-off-by: Kai Mäkisara <Kai.Makisara@kolumbus.fi> Link: https://lore.kernel.org/r/20250120194925.44432-4-Kai.Makisara@kolumbus.fi Reviewed-by: John Meneghini <jmeneghi@redhat.com> Tested-by: John Meneghini <jmeneghi@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent a5d518c commit 341128d

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

drivers/scsi/st.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,11 @@ static const char *st_formats[] = {
163163

164164
static int debugging = DEBUG;
165165

166+
/* Setting these non-zero may risk recognizing resets */
166167
#define MAX_RETRIES 0
167168
#define MAX_WRITE_RETRIES 0
168169
#define MAX_READY_RETRIES 0
170+
169171
#define NO_TAPE NOT_READY
170172

171173
#define ST_TIMEOUT (900 * HZ)
@@ -357,10 +359,18 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
357359
{
358360
int result = SRpnt->result;
359361
u8 scode;
362+
unsigned int ctr;
360363
DEB(const char *stp;)
361364
char *name = STp->name;
362365
struct st_cmdstatus *cmdstatp;
363366

367+
ctr = scsi_get_ua_por_ctr(STp->device);
368+
if (ctr != STp->por_ctr) {
369+
STp->por_ctr = ctr;
370+
STp->pos_unknown = 1; /* ASC => power on / reset */
371+
st_printk(KERN_WARNING, STp, "Power on/reset recognized.");
372+
}
373+
364374
if (!result)
365375
return 0;
366376

@@ -413,10 +423,11 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
413423
if (cmdstatp->have_sense &&
414424
cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17)
415425
STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */
416-
if (cmdstatp->have_sense && scode == UNIT_ATTENTION && cmdstatp->sense_hdr.asc == 0x29)
426+
if (cmdstatp->have_sense && scode == UNIT_ATTENTION &&
427+
cmdstatp->sense_hdr.asc == 0x29 && !STp->pos_unknown) {
417428
STp->pos_unknown = 1; /* ASC => power on / reset */
418-
419-
STp->pos_unknown |= STp->device->was_reset;
429+
st_printk(KERN_WARNING, STp, "Power on/reset recognized.");
430+
}
420431

421432
if (cmdstatp->have_sense &&
422433
scode == RECOVERED_ERROR
@@ -968,6 +979,7 @@ static int test_ready(struct scsi_tape *STp, int do_wait)
968979
{
969980
int attentions, waits, max_wait, scode;
970981
int retval = CHKRES_READY, new_session = 0;
982+
unsigned int ctr;
971983
unsigned char cmd[MAX_COMMAND_SIZE];
972984
struct st_request *SRpnt = NULL;
973985
struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
@@ -1024,6 +1036,13 @@ static int test_ready(struct scsi_tape *STp, int do_wait)
10241036
}
10251037
}
10261038

1039+
ctr = scsi_get_ua_new_media_ctr(STp->device);
1040+
if (ctr != STp->new_media_ctr) {
1041+
STp->new_media_ctr = ctr;
1042+
new_session = 1;
1043+
DEBC_printk(STp, "New tape session.");
1044+
}
1045+
10271046
retval = (STp->buffer)->syscall_result;
10281047
if (!retval)
10291048
retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY;
@@ -3639,8 +3658,6 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
36393658
goto out;
36403659
}
36413660
reset_state(STp); /* Clears pos_unknown */
3642-
/* remove this when the midlevel properly clears was_reset */
3643-
STp->device->was_reset = 0;
36443661

36453662
/* Fix the device settings after reset, ignore errors */
36463663
if (mtc.mt_op == MTREW || mtc.mt_op == MTSEEK ||
@@ -4402,6 +4419,9 @@ static int st_probe(struct device *dev)
44024419
goto out_idr_remove;
44034420
}
44044421

4422+
tpnt->new_media_ctr = scsi_get_ua_new_media_ctr(SDp);
4423+
tpnt->por_ctr = scsi_get_ua_por_ctr(SDp);
4424+
44054425
dev_set_drvdata(dev, tpnt);
44064426

44074427

drivers/scsi/st.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ struct scsi_tape {
179179
int recover_count; /* From tape opening */
180180
int recover_reg; /* From last status call */
181181

182+
/* The saved values of midlevel counters */
183+
unsigned int new_media_ctr;
184+
unsigned int por_ctr;
185+
182186
#if DEBUG
183187
unsigned char write_pending;
184188
int nbr_finished;

include/scsi/scsi_device.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,12 @@ static inline int scsi_device_busy(struct scsi_device *sdev)
687687
return sbitmap_weight(&sdev->budget_map);
688688
}
689689

690+
/* Macros to access the UNIT ATTENTION counters */
691+
#define scsi_get_ua_new_media_ctr(sdev) \
692+
((const unsigned int)(sdev->ua_new_media_ctr))
693+
#define scsi_get_ua_por_ctr(sdev) \
694+
((const unsigned int)(sdev->ua_por_ctr))
695+
690696
#define MODULE_ALIAS_SCSI_DEVICE(type) \
691697
MODULE_ALIAS("scsi:t-" __stringify(type) "*")
692698
#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"

0 commit comments

Comments
 (0)