Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kai Mäkisara and committed by
Martin K. Petersen
341128df a5d518cd

+35 -5
+25 -5
drivers/scsi/st.c
··· 163 163 164 164 static int debugging = DEBUG; 165 165 166 + /* Setting these non-zero may risk recognizing resets */ 166 167 #define MAX_RETRIES 0 167 168 #define MAX_WRITE_RETRIES 0 168 169 #define MAX_READY_RETRIES 0 170 + 169 171 #define NO_TAPE NOT_READY 170 172 171 173 #define ST_TIMEOUT (900 * HZ) ··· 359 357 { 360 358 int result = SRpnt->result; 361 359 u8 scode; 360 + unsigned int ctr; 362 361 DEB(const char *stp;) 363 362 char *name = STp->name; 364 363 struct st_cmdstatus *cmdstatp; 364 + 365 + ctr = scsi_get_ua_por_ctr(STp->device); 366 + if (ctr != STp->por_ctr) { 367 + STp->por_ctr = ctr; 368 + STp->pos_unknown = 1; /* ASC => power on / reset */ 369 + st_printk(KERN_WARNING, STp, "Power on/reset recognized."); 370 + } 365 371 366 372 if (!result) 367 373 return 0; ··· 423 413 if (cmdstatp->have_sense && 424 414 cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17) 425 415 STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */ 426 - if (cmdstatp->have_sense && scode == UNIT_ATTENTION && cmdstatp->sense_hdr.asc == 0x29) 416 + if (cmdstatp->have_sense && scode == UNIT_ATTENTION && 417 + cmdstatp->sense_hdr.asc == 0x29 && !STp->pos_unknown) { 427 418 STp->pos_unknown = 1; /* ASC => power on / reset */ 428 - 429 - STp->pos_unknown |= STp->device->was_reset; 419 + st_printk(KERN_WARNING, STp, "Power on/reset recognized."); 420 + } 430 421 431 422 if (cmdstatp->have_sense && 432 423 scode == RECOVERED_ERROR ··· 979 968 { 980 969 int attentions, waits, max_wait, scode; 981 970 int retval = CHKRES_READY, new_session = 0; 971 + unsigned int ctr; 982 972 unsigned char cmd[MAX_COMMAND_SIZE]; 983 973 struct st_request *SRpnt = NULL; 984 974 struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; ··· 1034 1022 break; 1035 1023 } 1036 1024 } 1025 + } 1026 + 1027 + ctr = scsi_get_ua_new_media_ctr(STp->device); 1028 + if (ctr != STp->new_media_ctr) { 1029 + STp->new_media_ctr = ctr; 1030 + new_session = 1; 1031 + DEBC_printk(STp, "New tape session."); 1037 1032 } 1038 1033 1039 1034 retval = (STp->buffer)->syscall_result; ··· 3658 3639 goto out; 3659 3640 } 3660 3641 reset_state(STp); /* Clears pos_unknown */ 3661 - /* remove this when the midlevel properly clears was_reset */ 3662 - STp->device->was_reset = 0; 3663 3642 3664 3643 /* Fix the device settings after reset, ignore errors */ 3665 3644 if (mtc.mt_op == MTREW || mtc.mt_op == MTSEEK || ··· 4418 4401 "st: Can't allocate statistics.\n"); 4419 4402 goto out_idr_remove; 4420 4403 } 4404 + 4405 + tpnt->new_media_ctr = scsi_get_ua_new_media_ctr(SDp); 4406 + tpnt->por_ctr = scsi_get_ua_por_ctr(SDp); 4421 4407 4422 4408 dev_set_drvdata(dev, tpnt); 4423 4409
+4
drivers/scsi/st.h
··· 179 179 int recover_count; /* From tape opening */ 180 180 int recover_reg; /* From last status call */ 181 181 182 + /* The saved values of midlevel counters */ 183 + unsigned int new_media_ctr; 184 + unsigned int por_ctr; 185 + 182 186 #if DEBUG 183 187 unsigned char write_pending; 184 188 int nbr_finished;
+6
include/scsi/scsi_device.h
··· 687 687 return sbitmap_weight(&sdev->budget_map); 688 688 } 689 689 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 + 690 696 #define MODULE_ALIAS_SCSI_DEVICE(type) \ 691 697 MODULE_ALIAS("scsi:t-" __stringify(type) "*") 692 698 #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"