patch-2.0.1 linux/drivers/scsi/st.c

Next file: linux/drivers/sound/.blurb
Previous file: linux/drivers/scsi/sg.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.0/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
@@ -11,7 +11,7 @@
   Copyright 1992 - 1996 Kai Makisara
 		 email Kai.Makisara@metla.fi
 
-  Last modified: Tue May 14 17:58:12 1996 by makisara@kai.makisara.fi
+  Last modified: Sun Jun 30 15:26:23 1996 by root@kai.makisara.fi
   Some small formal changes - aeb, 950809
 */
 
@@ -143,6 +143,8 @@
   }
 #endif
   scode = sense[2] & 0x0f;
+
+#if !DEBUG
   if (!(driver_byte(result) & DRIVER_SENSE) ||
       ((sense[0] & 0x70) == 0x70 &&
        scode != NO_SENSE &&
@@ -152,15 +154,14 @@
        scode != VOLUME_OVERFLOW &&
        SCpnt->data_cmnd[0] != MODE_SENSE &&
        SCpnt->data_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
-#if !DEBUG
     if (driver_byte(result) & DRIVER_SENSE) {
       printk(KERN_WARNING "st%d: Error with sense data: ", dev);
       print_sense("st", SCpnt);
     }
     else
       printk(KERN_WARNING "st%d: Error %x.\n", dev, result);
-#endif
   }
+#endif
 
   if ((sense[0] & 0x70) == 0x70 &&
       scode == RECOVERED_ERROR
@@ -172,7 +173,7 @@
     scsi_tapes[dev].recover_count++;
     scsi_tapes[dev].mt_status->mt_erreg += (1 << MT_ST_SOFTERR_SHIFT);
 #if DEBUG
-    if (debugging) {  /* This is compiled always on purpose */
+    if (debugging) {
       if (SCpnt->data_cmnd[0] == READ_6)
 	stp = "read";
       else if (SCpnt->data_cmnd[0] == WRITE_6)
@@ -380,16 +381,17 @@
       return (-EBUSY);
 
     if ((STp->buffer)->last_result_fatal != 0) {
-      printk(KERN_ERR "st%d: Error on flush.\n", TAPE_NR(STp->devt));
       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 	  (SCpnt->sense_buffer[2] & 0x40) &&
-	  (SCpnt->sense_buffer[2] & 0x0f) != VOLUME_OVERFLOW) {
+	  (SCpnt->sense_buffer[2] & 0x0f) == NO_SENSE) {
 	STp->dirty = 0;
 	(STp->buffer)->buffer_bytes = 0;
 	result = (-ENOSPC);
       }
-      else
+      else {
+	printk(KERN_ERR "st%d: Error on flush.\n", TAPE_NR(STp->devt));
 	result = (-EIO);
+      }
       STp->drv_block = (-1);
     }
     else {
@@ -455,7 +457,8 @@
       result = st_int_ioctl(inode, MTBSR, backspace);
   }
   else if ((STp->eof == ST_FM) && !STp->eof_hit) {
-    (STp->mt_status)->mt_fileno++;
+    if ((STp->mt_status)->mt_fileno >= 0)
+      (STp->mt_status)->mt_fileno++;
     STp->drv_block = 0;
   }
 
@@ -832,7 +835,13 @@
 
 	SCpnt->request.rq_status = RQ_INACTIVE;  /* Mark as not busy */
 
-	if ((STp->buffer)->last_result_fatal != 0)
+	if ((STp->buffer)->last_result_fatal != 0 &&
+	    ((SCpnt->sense_buffer[0] & 0x70) != 0x70 ||
+	     (SCpnt->sense_buffer[2] & 0x4f) != 0x40 ||
+	     ((SCpnt->sense_buffer[0] & 0x80) != 0 &&
+	      (SCpnt->sense_buffer[3] | SCpnt->sense_buffer[4] |
+	       SCpnt->sense_buffer[5] |
+	       SCpnt->sense_buffer[6]) == 0)))  /* Filter out successful write at EOM */
 	  printk(KERN_ERR "st%d: Error on write filemark.\n", dev);
 	else {
 	  if ((STp->mt_status)->mt_fileno >= 0)
@@ -1266,6 +1275,9 @@
 #endif
 	  if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) { /* extended sense */
 
+	    if ((SCpnt->sense_buffer[2] & 0x0f) == BLANK_CHECK)
+		SCpnt->sense_buffer[2] &= 0xcf; /* No need for EOM in this case */
+
 	    if ((SCpnt->sense_buffer[2] & 0xe0) != 0) { /* EOF, EOM, or ILI */
 
 	      if ((SCpnt->sense_buffer[0] & 0x80) != 0)
@@ -1309,31 +1321,31 @@
 		  SCpnt = NULL;
 		}
 	      }
-	      else if (SCpnt->sense_buffer[2] & 0x40) {
-		STp->eof = ST_EOM_OK;
+	      else if (SCpnt->sense_buffer[2] & 0x80) { /* FM overrides EOM */
+		STp->eof = ST_FM;
 		if (STp->block_size == 0)
-		  (STp->buffer)->buffer_bytes = bytes - transfer;
+		  (STp->buffer)->buffer_bytes = 0;
 		else
 		  (STp->buffer)->buffer_bytes =
 		    bytes - transfer * STp->block_size;
 #if DEBUG
 		if (debugging)
-		  printk(ST_DEB_MSG "st%d: EOM detected (%d bytes read).\n", dev,
-			 (STp->buffer)->buffer_bytes);
+		  printk(ST_DEB_MSG
+		    "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
+			 dev, (STp->buffer)->buffer_bytes, total);
 #endif
 	      }
-	      else if (SCpnt->sense_buffer[2] & 0x80) {
-		STp->eof = ST_FM;
+	      else if (SCpnt->sense_buffer[2] & 0x40) {
+		STp->eof = ST_EOM_OK;
 		if (STp->block_size == 0)
-		  (STp->buffer)->buffer_bytes = 0;
+		  (STp->buffer)->buffer_bytes = bytes - transfer;
 		else
 		  (STp->buffer)->buffer_bytes =
 		    bytes - transfer * STp->block_size;
 #if DEBUG
 		if (debugging)
-		  printk(ST_DEB_MSG
-		    "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",
-			 dev, (STp->buffer)->buffer_bytes, total);
+		  printk(ST_DEB_MSG "st%d: EOM detected (%d bytes read).\n", dev,
+			 (STp->buffer)->buffer_bytes);
 #endif
 	      }
 	    } /* end of EOF, EOM, ILI test */
@@ -1409,7 +1421,7 @@
 	    (STp->mt_status)->mt_fileno++;
 	}
 	if (total == 0 && STp->eof == ST_EOM_OK)
-	  return (-EIO);  /* ST_EOM_ERROR not used in read */
+	  return (-ENOSPC);  /* ST_EOM_ERROR not used in read */
 	return total;
       }
 
@@ -1677,7 +1689,7 @@
 
   SCpnt->request.rq_status = RQ_INACTIVE;  /* Mark as not busy */
   STp->compression_changed = TRUE;
-  return 0;  /* Not implemented yet */
+  return 0;
 }
 
 
@@ -2085,7 +2097,16 @@
 	  (SCpnt->sense_buffer[4] << 16) +
 	  (SCpnt->sense_buffer[5] << 8) +
 	  SCpnt->sense_buffer[6] );
-     if ( (cmd_in == MTFSF) || (cmd_in == MTFSFM) ) {
+     if (cmd_in == MTWEOF &&
+       (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
+       (SCpnt->sense_buffer[2] & 0x4f) == 0x40 &&
+       ((SCpnt->sense_buffer[0] & 0x80) == 0 || undone == 0)) {
+       ioctl_result = 0;  /* EOF written succesfully at EOM */
+       if (fileno >= 0)
+	 fileno++;
+       (STp->mt_status)->mt_fileno = fileno;
+     }
+     else if ( (cmd_in == MTFSF) || (cmd_in == MTFSFM) ) {
        if (fileno >= 0)
 	 (STp->mt_status)->mt_fileno = fileno - undone ;
        else
@@ -2518,11 +2539,13 @@
        if (STp->eof_hit) {
 	 if (mtc.mt_op == MTFSF || mtc.mt_op == MTEOM) {
 	   mtc.mt_count -= 1;
-	   (STp->mt_status)->mt_fileno += 1;
+	   if ((STp->mt_status)->mt_fileno >= 0)
+	     (STp->mt_status)->mt_fileno += 1;
 	 }
 	 else if (mtc.mt_op == MTBSF) {
 	   mtc.mt_count += 1;
-	   (STp->mt_status)->mt_fileno += 1;
+	   if ((STp->mt_status)->mt_fileno >= 0)
+	     (STp->mt_status)->mt_fileno += 1;
 	 }
        }
 
@@ -2670,6 +2693,9 @@
        (STp->mt_status)->mt_gstat |= GMT_DR_OPEN(0xffffffff);
      if (STps->at_sm)
        (STp->mt_status)->mt_gstat |= GMT_SM(0xffffffff);
+     if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
+	 STp->drv_buffer != 0)
+       (STp->mt_status)->mt_gstat |= GMT_IM_REP_EN(0xffffffff);
 
      memcpy_tofs((char *)arg, (char *)(STp->mt_status),
 		 sizeof(struct mtget));

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov