patch-2.0.5 linux/drivers/scsi/u14-34f.c

Next file: linux/drivers/scsi/u14-34f.h
Previous file: linux/drivers/scsi/sd.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.4/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
@@ -1,6 +1,10 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      09 Jul 1996 rev. 2.11 for linux 2.0.4
+ *          "Data over/under-run" no longer implies a redo on all targets.
+ *          Number of internal retries is now limited.
+ *
  *      16 Apr 1996 rev. 2.10 for linux 1.3.90
  *          New argument "reset_flags" to the reset routine.
  *
@@ -199,6 +203,7 @@
 #define MAX_MAILBOXES 16
 #define MAX_SGLIST 32
 #define MAX_SAFE_SGLIST 16
+#define MAX_INTERNAL_RETRIES 64
 #define MAX_CMD_PER_LUN 2
 
 #define FALSE 0
@@ -280,6 +285,8 @@
    int in_reset;                        /* True if board is doing a reset */
    int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
    int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
+   unsigned int retries;                /* Number of internal retries */
+   unsigned long last_retried_pid;      /* Pid of last retried command */
    unsigned char subversion;            /* Bus type, either ISA or ESA */
    unsigned char heads;
    unsigned char sectors;
@@ -763,6 +770,8 @@
       return SCSI_RESET_ERROR;
       }
 
+   HD(j)->retries = 0;
+
    for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
 
    for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
@@ -972,6 +981,8 @@
 
 	       HD(j)->target_time_out[SCpnt->target] = 0;
 
+               if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
+
 	       break;
 	    case ASST:     /* Selection Time Out */
 
@@ -983,20 +994,27 @@
 		  }
 
 	       break;
-	    case 0x92:     /* Data over/under-run */
+
+            /* Perform a limited number of internal retries */
 	    case 0x93:     /* Unexpected bus free */
 	    case 0x94:     /* Target bus phase sequence failure */
 	    case 0x96:     /* Illegal SCSI command */
 	    case 0xa3:     /* SCSI bus reset error */
 
-	       if (SCpnt->device->type != TYPE_TAPE)
-		  status = DID_BUS_BUSY << 16;
-	       else
-		  status = DID_ERROR << 16;
-
 	       for (k = 0; k < MAX_TARGET; k++) 
 		  HD(j)->target_reset[k] = TRUE;
 
+	    case 0x92:     /* Data over/under-run */
+
+	       if (SCpnt->device->type != TYPE_TAPE
+                   && HD(j)->retries < MAX_INTERNAL_RETRIES) {
+		  status = DID_BUS_BUSY << 16;
+		  HD(j)->retries++;
+                  HD(j)->last_retried_pid = SCpnt->pid;
+                  }
+	       else 
+		  status = DID_ERROR << 16;
+
 	       break;
 	    case 0x01:     /* Invalid command */
 	    case 0x02:     /* Invalid parameters */
@@ -1023,7 +1041,7 @@
 	      spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
 	     do_trace)
 #endif
-	    printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
+	    printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
 		   " target %d:%d, pid %ld, count %d.\n",
 		   BN(j), i, spp->adapter_status, spp->target_status,
 		   SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);

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