@@ -163,9 +163,11 @@ static const char *st_formats[] = {
163163
164164static 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
@@ -952,7 +963,6 @@ static void reset_state(struct scsi_tape *STp)
952963 STp -> partition = find_partition (STp );
953964 if (STp -> partition < 0 )
954965 STp -> partition = 0 ;
955- STp -> new_partition = STp -> partition ;
956966 }
957967}
958968
@@ -969,6 +979,7 @@ static int test_ready(struct scsi_tape *STp, int do_wait)
969979{
970980 int attentions , waits , max_wait , scode ;
971981 int retval = CHKRES_READY , new_session = 0 ;
982+ unsigned int ctr ;
972983 unsigned char cmd [MAX_COMMAND_SIZE ];
973984 struct st_request * SRpnt = NULL ;
974985 struct st_cmdstatus * cmdstatp = & STp -> buffer -> cmdstat ;
@@ -1025,6 +1036,13 @@ static int test_ready(struct scsi_tape *STp, int do_wait)
10251036 }
10261037 }
10271038
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+
10281046 retval = (STp -> buffer )-> syscall_result ;
10291047 if (!retval )
10301048 retval = new_session ? CHKRES_NEW_SESSION : CHKRES_READY ;
@@ -2930,14 +2948,17 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
29302948 if (cmd_in == MTSETDENSITY ) {
29312949 (STp -> buffer )-> b_data [4 ] = arg ;
29322950 STp -> density_changed = 1 ; /* At least we tried ;-) */
2951+ STp -> changed_density = arg ;
29332952 } else if (cmd_in == SET_DENS_AND_BLK )
29342953 (STp -> buffer )-> b_data [4 ] = arg >> 24 ;
29352954 else
29362955 (STp -> buffer )-> b_data [4 ] = STp -> density ;
29372956 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK ) {
29382957 ltmp = arg & MT_ST_BLKSIZE_MASK ;
2939- if (cmd_in == MTSETBLK )
2958+ if (cmd_in == MTSETBLK ) {
29402959 STp -> blksize_changed = 1 ; /* At least we tried ;-) */
2960+ STp -> changed_blksize = arg ;
2961+ }
29412962 } else
29422963 ltmp = STp -> block_size ;
29432964 (STp -> buffer )-> b_data [9 ] = (ltmp >> 16 );
@@ -3636,9 +3657,23 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
36363657 retval = (- EIO );
36373658 goto out ;
36383659 }
3639- reset_state (STp );
3640- /* remove this when the midlevel properly clears was_reset */
3641- STp -> device -> was_reset = 0 ;
3660+ reset_state (STp ); /* Clears pos_unknown */
3661+
3662+ /* Fix the device settings after reset, ignore errors */
3663+ if (mtc .mt_op == MTREW || mtc .mt_op == MTSEEK ||
3664+ mtc .mt_op == MTEOM ) {
3665+ if (STp -> can_partitions ) {
3666+ /* STp->new_partition contains the
3667+ * latest partition set
3668+ */
3669+ STp -> partition = 0 ;
3670+ switch_partition (STp );
3671+ }
3672+ if (STp -> density_changed )
3673+ st_int_ioctl (STp , MTSETDENSITY , STp -> changed_density );
3674+ if (STp -> blksize_changed )
3675+ st_int_ioctl (STp , MTSETBLK , STp -> changed_blksize );
3676+ }
36423677 }
36433678
36443679 if (mtc .mt_op != MTNOP && mtc .mt_op != MTSETBLK &&
@@ -4384,6 +4419,9 @@ static int st_probe(struct device *dev)
43844419 goto out_idr_remove ;
43854420 }
43864421
4422+ tpnt -> new_media_ctr = scsi_get_ua_new_media_ctr (SDp );
4423+ tpnt -> por_ctr = scsi_get_ua_por_ctr (SDp );
4424+
43874425 dev_set_drvdata (dev , tpnt );
43884426
43894427
@@ -4665,6 +4703,24 @@ options_show(struct device *dev, struct device_attribute *attr, char *buf)
46654703}
46664704static DEVICE_ATTR_RO (options );
46674705
4706+ /**
4707+ * position_lost_in_reset_show - Value 1 indicates that reads, writes, etc.
4708+ * are blocked because a device reset has occurred and no operation positioning
4709+ * the tape has been issued.
4710+ * @dev: struct device
4711+ * @attr: attribute structure
4712+ * @buf: buffer to return formatted data in
4713+ */
4714+ static ssize_t position_lost_in_reset_show (struct device * dev ,
4715+ struct device_attribute * attr , char * buf )
4716+ {
4717+ struct st_modedef * STm = dev_get_drvdata (dev );
4718+ struct scsi_tape * STp = STm -> tape ;
4719+
4720+ return sprintf (buf , "%d" , STp -> pos_unknown );
4721+ }
4722+ static DEVICE_ATTR_RO (position_lost_in_reset );
4723+
46684724/* Support for tape stats */
46694725
46704726/**
@@ -4849,6 +4905,7 @@ static struct attribute *st_dev_attrs[] = {
48494905 & dev_attr_default_density .attr ,
48504906 & dev_attr_default_compression .attr ,
48514907 & dev_attr_options .attr ,
4908+ & dev_attr_position_lost_in_reset .attr ,
48524909 NULL ,
48534910};
48544911
0 commit comments