[4489] in linux-scsi channel archive

home help back first fref pref prev next nref lref last post

Making Future Domain 950 work

daemon@ATHENA.MIT.EDU (Pavel Machek)
Sat Aug 1 05:13:47 1998

Date: 	Fri, 31 Jul 1998 23:56:14 +0200
From: Pavel Machek <pavel@bug.ucw.cz>
To: linux-scsi@vger.rutgers.edu, craig@is.co.za, torvalds@transmeta.com,
        alan@lxorguk.ukuu.org.uk

Hi!

This patch makes seagate driver actually work for me (what is currenly
in 2.1. could not actually work - while(jiffies<clock) in disabled
interrupts is _bad_ idea. I also cleaned things up a lot.

Please apply.

								Pavel

--- clean/drivers/scsi/seagate.c	Tue Jun  9 22:34:48 1998
+++ linux/drivers/scsi/seagate.c	Fri Jul 31 23:34:27 1998
@@ -1,30 +1,23 @@
 /*
  *    seagate.c Copyright (C) 1992, 1993 Drew Eckhardt
  *      low level scsi driver for ST01/ST02, Future Domain TMC-885,
- *      TMC-950  by
- *
- *              Drew Eckhardt
- *
- *      <drew@colorado.edu>
+ *      TMC-950 by Drew Eckhardt <drew@colorado.edu>
  *
  *      Note : TMC-880 boards don't work because they have two bits in
  *              the status register flipped, I'll fix this "RSN"
+ *	[why do I have strong feeling that above message is from 1993? :-) pavel@ucw.cz]
  *
  *      This card does all the I/O via memory mapped I/O, so there is no need
  *      to check or allocate a region of the I/O address space.
  */
 
-/* Modified 1996 to use new read{b,w,l}, write{b,w,l}, and phys_to_virt
-   macros. This meant redefining st0x_cr_sr and st0x_dr, as well as
-   replacing the "DATA = foo;" and "CONTROL = foo;" structures with 
-   WRITE_DATA(foo) and WRITE_CONTROL(foo) macros.
-
-   Replaced assembler routines with C. There's probably a performance hit,
-   but I only have a cdrom and can't tell. Define SEAGATE_USE_ASM if you
-   want the old assembler code.
-
-   Look for the string "SJT" for details.
-
+/* 1996 - to use new read{b,w,l}, write{b,w,l}, and phys_to_virt
+ * macros, replaced assembler routines with C. There's probably a
+ * performance hit, but I only have a cdrom and can't tell. Define
+ * SEAGATE_USE_ASM if you want the old assembler code -- SJT
+ *
+ * 1998-jul-29 - created DPRINTK macros and made it work under 
+ * linux 2.1.112, simplified some #defines etc. <pavel@ucw.cz>
  */
 
 /*
@@ -63,13 +56,12 @@
  *      Will use older seagate assembly code. should be (very small amount)
  *      Faster.
  *
- * -DSLOW_HANDSHAKE
+ * -DSLOW_RATE=50
  *      Will allow compatibility with broken devices that don't
  *      handshake fast enough (ie, some CD ROM's) for the Seagate
  *      code.
  *
- * -DSLOW_RATE=x
- *      x is some number, It will let you specify a default
+ *      50 is some number, It will let you specify a default
  *      transfer rate if handshaking isn't working correctly.
  *
  * -DOLDCNTDATASCEME  There is a new sceme to set the CONTROL
@@ -97,16 +89,27 @@
 #include <linux/string.h>
 #include <linux/config.h>
 #include <linux/proc_fs.h>
+#include <linux/init.h>
 
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
 #include "seagate.h"
 #include "constants.h"
-#include<linux/stat.h>
+#include <linux/stat.h>
 #include <asm/uaccess.h>
 #include "sd.h"
 #include <scsi/scsi_ioctl.h>
+#include <asm/delay.h>
+
+
+#ifdef DEBUG
+#define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0)
+#define DANY( msg... ) DPRINTK( 0xffff, msg );
+#else
+#define DPRINTK( when, msg... )
+#define DANY( msg... )
+#endif
 
 static struct proc_dir_entry proc_scsi_seagate =
 {
@@ -122,19 +131,13 @@
 #define FAST
 #endif
 
-#if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
-#define SLOW_HANDSHAKE
-#endif
-
-#if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
-#define SLOW_RATE 50
-#endif
-
 #if defined(LINKED)
-#undef LINKED                           /* Linked commands are currently
-                                           broken! */
+#undef LINKED		/* Linked commands are currently broken! */
 #endif
 
+#if defined(OVERRIDE) && !defined(CONTROLLER)
+#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
+#endif
 
 /*
 	Thanks to Brian Antoine for the example code in his Messy-Loss ST-01
@@ -206,7 +210,7 @@
 #define PHASE_MSGIN 0x40
 #define PHASE_MSGOUT 0x80
 #define PHASE_STATUSIN 0x100
-#define PHASE_ETC (PHASE_DATAIN | PHASE_DATA_OUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)
+#define PHASE_ETC (PHASE_DATAIN | PHASE_DATAOUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)
 #define PRINT_COMMAND 0x200
 #define PHASE_EXIT 0x400
 #define PHASE_RESELECT 0x800
@@ -223,8 +227,6 @@
 #define ST0X_BUS_FREE_DELAY 25
 #define ST0X_SELECTION_DELAY 25
 
-#define eoi() __asm__("push %%eax\nmovb $0x20, %%al\noutb %%al, $0x20\npop %%eax"::)
-	
 #define SEAGATE 1	/* these determine the type of the controller */
 #define FD	2
 
@@ -244,7 +246,6 @@
                                            location.  */
 #ifdef notyet
 static volatile int abort_confirm = 0;
-
 #endif
 
 static unsigned long st0x_cr_sr;        /* control register write, status
@@ -262,15 +263,13 @@
 static unsigned char controller_type = 0;       /* set to SEAGATE for ST0x
                                                    boards or FD for TMC-8xx
                                                    boards */
-static unsigned char irq = IRQ;
+static int irq = IRQ;
 
 #define retcode(result) (((result) << 16) | (message << 8) | status)
-#define STATUS (readb(st0x_cr_sr))
-#define DATA (readb(st0x_dr))
-/* SJT: Start. */
-#define WRITE_CONTROL(d) writeb((d), st0x_cr_sr)
-#define WRITE_DATA(d) writeb((d), st0x_dr)
-/* SJT: End. */
+#define STATUS ((u8) readb(st0x_cr_sr))
+#define DATA ((u8) readb(st0x_dr))
+#define WRITE_CONTROL(d) { writeb((d), st0x_cr_sr); }
+#define WRITE_DATA(d) { writeb((d), st0x_dr); }
 
 void st0x_setup (char *str, int *ints)
 {
@@ -302,9 +301,8 @@
 }
 Signature;
 
-static const Signature signatures[] =
+static const Signature __initdata signatures[] =
 {
-#ifdef CONFIG_SCSI_SEAGATE
   {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
   {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 
@@ -331,9 +329,7 @@
   {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
   {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
   {"FUTURE DOMAIN TMC-950", 5, 21, FD},
-#endif                                  /* CONFIG_SCSI_SEAGATE */
-}
-;
+};
 
 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
 #endif /* n OVERRIDE */
@@ -348,10 +344,11 @@
 
 #ifdef FAST
 static int fast = 1;
-
+#else
+#define fast 0
 #endif
 
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
 /*
  * Support for broken devices :
  * The Seagate board has a handshaking problem.  Namely, a lack
@@ -387,10 +384,13 @@
  * the best thing for us to do will be to calibrate a timing
  * loop in the initialization code using the timer chip before
  * gettimeofday() can screw with it.
+ *
+ * FIXME: this is broken (not borken :-). Empty loop costs less than
+ * loop with ISA access in it! -- pavel@ucw.cz
  */
 
 static int borken_calibration = 0;
-static void borken_init (void)
+static void __init borken_init (void)
 {
   register int count = 0, start = jiffies + 1, stop = start + 25;
 
@@ -399,53 +399,43 @@
 
 /*
  * Ok, we now have a count for .25 seconds.  Convert to a
- * count per second and divide by transfer rate in K.
- */
+ * count per second and divide by transfer rate in K.  */
 
   borken_calibration = (count * 4) / (SLOW_RATE * 1024);
 
   if (borken_calibration < 1)
     borken_calibration = 1;
-#if (DEBUG & DEBUG_BORKEN)
-  printk ("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n",
-          hostno, BORKEN_RATE, borken_calibration);
-#endif
 }
 
 static inline void borken_wait (void)
 {
   register int count;
 
-  for (count = borken_calibration; count && (STATUS & STAT_REQ);
-       --count) ;
+  for (count = borken_calibration; count && (STATUS & STAT_REQ); --count) ;
 #if (DEBUG & DEBUG_BORKEN)
   if (count)
     printk ("scsi%d : borken timeout\n", hostno);
 #endif
 }
 
-#endif /* def SLOW_HANDSHAKE */
+#endif /* def SLOW_RATE */
 
-int seagate_st0x_detect (Scsi_Host_Template * tpnt)
+#define ULOOP( i ) for (clock = i;;udelay(1))
+#define TIMEOUT (!(clock--))
+
+int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
 {
   struct Scsi_Host *instance;
-
-#ifndef OVERRIDE
   int i, j;
 
-#endif
-
   tpnt->proc_dir = &proc_scsi_seagate;
 /*
  *    First, we try for the manual override.
  */
-#ifdef DEBUG
-  printk ("Autodetecting ST0x / TMC-8xx\n");
-#endif
+  DANY ("Autodetecting ST0x / TMC-8xx\n");
 
-  if (hostno != -1)
-  {
-    printk ("ERROR : seagate_st0x_detect() called twice.\n");
+  if (hostno != -1) {
+    printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
     return 0;
   }
 
@@ -456,17 +446,10 @@
   {
 #ifdef OVERRIDE
     base_address = OVERRIDE;
-
-/* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
-#ifdef CONTROLLER
     controller_type = CONTROLLER;
-#else
-#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
-#endif /* CONTROLLER */
-#ifdef DEBUG
-    printk ("Base address overridden to %x, controller type is %s\n",
+
+    DANY("Base address overridden to %x, controller type is %s\n",
             base_address, controller_type == SEAGATE ? "SEAGATE" : "FD");
-#endif
 #else /* OVERRIDE */
 /*
  *    To detect this card, we simply look for the signature
@@ -493,33 +476,46 @@
   tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
   tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
 
-  if (base_address)
-  {
-    st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
-    st0x_dr = st0x_cr_sr + 0x200;
-#ifdef DEBUG
-    printk ("%s detected. Base address = %x, cr = %x, dr = %x\n",
-            tpnt->name, base_address, st0x_cr_sr, st0x_dr);
-#endif
+  if (!base_address) {
+    DANY ("ST0x / TMC-8xx not detected.\n");
+    return 0;
+  }
+
+  st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
+  st0x_dr = st0x_cr_sr + 0x200;
+
+  DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
+	tpnt->name, base_address, st0x_cr_sr, st0x_dr);
+
 /*
  *    At all times, we will use IRQ 5.  Should also check for IRQ3 if we
  *      loose our first interrupt.
  */
-    instance = scsi_register (tpnt, 0);
-    hostno = instance->host_no;
-    if (request_irq ((int) irq, do_seagate_reconnect_intr, SA_INTERRUPT,
-                (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL))
-    {
-      printk ("scsi%d : unable to allocate IRQ%d\n", hostno, (int) irq);
-      return 0;
-    }
-    instance->irq = irq;
-    instance->io_port = base_address;
-#ifdef SLOW_HANDSHAKE
-    borken_init ();
+  instance = scsi_register (tpnt, 0);
+  hostno = instance->host_no;
+  if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
+		   (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
+    printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
+    return 0;
+  }
+  instance->irq = irq;
+  instance->io_port = base_address;
+#ifdef SLOW_RATE
+  printk( "Calibrating borken timer... " );
+  borken_init ();
+  printk( " %d cycles per transfer\n", borken_calibration );
 #endif
 
-    printk ("%s options:"
+  printk( "This is one second... " );
+  {
+    int clock;
+    ULOOP( 1*1000*1000 ) {
+      volatile int x = STATUS;
+      if (TIMEOUT) break;
+    }
+  }
+
+  printk ("done, %s options:"
 #ifdef ARBITRATE
             " ARBITRATE"
 #endif
@@ -527,10 +523,9 @@
             " DEBUG"
 #endif
 #ifdef FAST
-#ifdef FAST32
-            " FAST32"
-#else
             " FAST"
+#ifdef FAST32
+            "32"
 #endif
 #endif
 #ifdef LINKED
@@ -542,8 +537,8 @@
 #ifdef SEAGATE_USE_ASM
             " SEAGATE_USE_ASM"
 #endif
-#ifdef SLOW_HANDSHAKE
-            " SLOW_HANDSHAKE"
+#ifdef SLOW_RATE
+            " SLOW_RATE"
 #endif
 #ifdef SWAPSTAT
             " SWAPSTAT"
@@ -551,16 +546,8 @@
 #ifdef SWAPCNTDATA
             " SWAPCNTDATA"
 #endif
-            "\n", tpnt->name);
-    return 1;
-  }
-  else
-  {
-#ifdef DEBUG
-    printk ("ST0x / TMC-8xx not detected.\n");
-#endif
-    return 0;
-  }
+	  "\n", tpnt->name);
+  return 1;
 }
 
 const char *seagate_st0x_info (struct Scsi_Host *shpnt)
@@ -585,7 +572,6 @@
 static int current_bufflen;
 
 #ifdef LINKED
-
 /*
  * linked_connected indicates whether or not we are currently connected to
  * linked_target, linked_lun and in an INFORMATION TRANSFER phase,
@@ -594,7 +580,6 @@
 
 static int linked_connected = 0;
 static unsigned char linked_target, linked_lun;
-
 #endif
 
 static void (*done_fn) (Scsi_Cmnd *) = NULL;
@@ -609,17 +594,14 @@
 #define RECONNECT_NOW   1
 #define CAN_RECONNECT   2
 
-#ifdef LINKED
-
 /*
  * LINKED_RIGHT indicates that we are currently connected to the correct target
  * for this command, LINKED_WRONG indicates that we are connected to the wrong
- * target.  Note that these imply CAN_RECONNECT.
+ * target. Note that these imply CAN_RECONNECT and require defined(LINKED).
  */
 
 #define LINKED_RIGHT    3
 #define LINKED_WRONG    4
-#endif
 
 /*
  * This determines if we are expecting to reconnect or not.
@@ -633,8 +615,7 @@
  * asserting SEL.
  */
 
-static void do_seagate_reconnect_intr (int irq, void *dev_id, 
-                                    struct pt_regs *regs)
+static void do_seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
   unsigned long flags;
 
@@ -643,15 +624,12 @@
   spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
-static void seagate_reconnect_intr (int irq, void *dev_id, 
-                                    struct pt_regs *regs)
+static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
   int temp;
   Scsi_Cmnd *SCtmp;
 
-#if (DEBUG & PHASE_RESELECT)
-  printk ("scsi%d : seagate_reconnect_intr() called\n", hostno);
-#endif
+  DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
 
   if (!should_reconnect)
     printk ("scsi%d: unexpected interrupt.\n", hostno);
@@ -659,11 +637,9 @@
   {
     should_reconnect = 0;
 
-#if (DEBUG & PHASE_RESELECT)
-    printk ("scsi%d : internal_command("
-            "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno,
+    DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
+            "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
             current_target, current_data, current_bufflen);
-#endif
 
     temp = internal_command (current_target, current_lun, current_cmnd,
                              current_data, current_bufflen, RECONNECT_NOW);
@@ -672,10 +648,8 @@
     {
       if (done_fn)
       {
-#if (DEBUG & PHASE_RESELECT)
-        printk ("scsi%d : done_fn(%d,%08x)", hostno,
+        DPRINTK (PHASE_RESELECT, "scsi%d : done_fn(%d,%08x)", hostno,
                 hostno, temp);
-#endif
         if (!SCint)
           panic ("SCint == NULL in seagate");
         SCtmp = SCint;
@@ -714,10 +689,7 @@
   current_data = (unsigned char *) SCpnt->request_buffer;
   current_bufflen = SCpnt->request_bufflen;
   SCint = SCpnt;
-  if (recursion_depth)
-  {
-    return 0;
-  };
+  if (recursion_depth) return 0;
   recursion_depth++;
   do
   {
@@ -729,22 +701,16 @@
     current_cmnd[SCpnt->cmd_len] |= 0x01;
     if (linked_connected)
     {
-#if (DEBUG & DEBUG_LINKED)
-      printk ("scsi%d : using linked commands, current I_T_L nexus is ",
-              hostno);
-#endif
+      DPRINTK (DEBUG_LINKED, 
+	       "scsi%d : using linked commands, current I_T_L nexus is ", hostno);
       if ((linked_target == current_target) && (linked_lun == current_lun))
       {
-#if (DEBUG & DEBUG_LINKED)
-        printk ("correct\n");
-#endif
+        DPRINTK (DEBUG_LINKED, "correct\n");
         reconnect = LINKED_RIGHT;
       }
       else
       {
-#if (DEBUG & DEBUG_LINKED)
-        printk ("incorrect\n");
-#endif
+        DPRINTK (DEBUG_LINKED, "incorrect\n");
         reconnect = LINKED_WRONG;
       }
     }
@@ -753,10 +719,8 @@
       reconnect = CAN_RECONNECT;
 
     result = internal_command (SCint->target, SCint->lun, SCint->cmnd,
-                               SCint->request_buffer, SCint->request_bufflen,
-                               reconnect);
-    if (msg_byte (result) == DISCONNECT)
-      break;
+                               SCint->request_buffer, SCint->request_bufflen, reconnect);
+    if (msg_byte (result) == DISCONNECT) break;
     SCtmp = SCint;
     SCint = NULL;
     SCtmp->result = result;
@@ -775,59 +739,33 @@
 }
 
 static int internal_command (unsigned char target, unsigned char lun, 
-                             const void *cmnd, void *buff, int bufflen, 
-                             int reselect)
+                             const void *cmnd, void *buff, int bufflen, int reselect)
 {
-  int len = 0;
   unsigned char *data = NULL;
   struct scatterlist *buffer = NULL;
-  int nobuffs = 0;
-  int clock;
-  int temp;
-
-#ifdef SLOW_HANDSHAKE
-  int borken;                           /* Does the current target require
-                                           Very Slow I/O ?  */
-#endif
-
-#if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT)
-  int transfered = 0;
-
-#endif
-
-#if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
-     (DEBUG & PHASE_EXIT))
-  int i;
-
-#endif
-
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
-  int phase = 0, newphase;
+  int clock, temp, nobuffs = 0, done = 0, len = 0;
+  unsigned long flags;
 
+#ifdef DEBUG
+  int transfered = 0, phase = 0, newphase;
 #endif
 
-  int done = 0;
-  unsigned char status = 0;
-  unsigned char message = 0;
   register unsigned char status_read;
+  unsigned char tmp_data, tmp_control, status = 0, message = 0;
 
-#ifndef OLDCNTDATASCEME
-  volatile unsigned char tmp_data;
-  volatile unsigned char tmp_control;
-#endif
   unsigned transfersize = 0, underflow = 0;
 
+#ifdef SLOW_RATE
+  int borken = (int) SCint->device->borken; /* Does the current target require
+					       Very Slow I/O ?  */
+#endif
+
   incommand = 0;
   st0x_aborted = 0;
 
-#ifdef SLOW_HANDSHAKE
-  borken = (int) SCint->device->borken;
-#endif
-
 #if (DEBUG & PRINT_COMMAND)
   printk ("scsi%d : target = %d, command = ", hostno, target);
   print_command ((unsigned char *) cmnd);
-  printk ("\n");
 #endif
 
 #if (DEBUG & PHASE_RESELECT)
@@ -864,9 +802,7 @@
   switch (reselect)
   {
     case RECONNECT_NOW:
-#if (DEBUG & PHASE_RESELECT)
-      printk ("scsi%d : phase RESELECT \n", hostno);
-#endif
+      DPRINTK ( PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
 
 /*
  *    At this point, we should find the logical or of our ID and the original
@@ -876,19 +812,14 @@
  *      target ID are asserted.  A valid initiator ID is not on the bus
  *      until IO is asserted, so we must wait for that.
  */
-      clock = jiffies + 10;
-      for (;;)
-      {
+      ULOOP( 100*1000 ) {
         temp = STATUS;
         if ((temp & STAT_IO) && !(temp & STAT_BSY))
           break;
 
-        if (jiffies > clock)
-        {
-#if (DEBUG & PHASE_RESELECT)
-          printk ("scsi%d : RESELECT timed out while waiting for IO .\n",
-                  hostno);
-#endif
+        if (TIMEOUT) {
+          DPRINTK (PHASE_RESELECT, 
+		   "scsi%d : RESELECT timed out while waiting for IO .\n", hostno);
           return (DID_BAD_INTR << 16);
         }
       }
@@ -900,10 +831,9 @@
 
       if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
       {
-#if (DEBUG & PHASE_RESELECT)
-        printk ("scsi%d : detected reconnect request to different target.\n"
-                "\tData bus = %d\n", hostno, temp);
-#endif
+        DPRINTK (PHASE_RESELECT,
+		 "scsi%d : detected reconnect request to different target.\n"
+		 "\tData bus = %d\n", hostno, temp);
         return (DID_BAD_INTR << 16);
       }
 
@@ -936,16 +866,14 @@
  *      BSY.
  */
 
-      for (clock = jiffies + 10; (jiffies < clock) && (STATUS & STAT_SEL);) ;
-
-      if (jiffies >= clock)
-      {
-        WRITE_CONTROL (BASE_CMD | CMD_INTR);
-#if (DEBUG & PHASE_RESELECT)
-        printk ("scsi%d : RESELECT timed out while waiting for SEL.\n", 
-                hostno);
-#endif
-        return (DID_BAD_INTR << 16);
+      ULOOP( 100*1000 ) {
+	if (!(STATUS & STAT_SEL)) break;
+	if (TIMEOUT) {
+	  WRITE_CONTROL (BASE_CMD | CMD_INTR);
+	  DPRINTK (PHASE_RESELECT,
+		   "scsi%d : RESELECT timed out while waiting for SEL.\n", hostno);
+	  return (DID_BAD_INTR << 16);
+	}
       }
 
       WRITE_CONTROL (BASE_CMD);
@@ -969,9 +897,7 @@
 
 #endif
 
-#if (DEBUG & PHASE_BUS_FREE)
-      printk ("scsi%d : phase = BUS FREE \n", hostno);
-#endif
+      DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n", hostno);
 
 /*
  *    BUS FREE PHASE
@@ -982,12 +908,13 @@
  *      eliminate wire glitch.
  */
 
+#ifndef ARBITRATE
+#error FIXME: this is broken: we may not use jiffies here - we are under cli(). It will hardlock.
       clock = jiffies + ST0X_BUS_FREE_DELAY;
 
-#if !defined (ARBITRATE)
       while (((STATUS | STATUS | STATUS) &
               (STAT_BSY | STAT_SEL)) &&
-             (!st0x_aborted) && (jiffies < clock)) ;
+             (!st0x_aborted) && (jiffies < clock));
 
       if (jiffies > clock)
         return retcode (DID_BUS_BUSY);
@@ -995,9 +922,7 @@
         return retcode (st0x_aborted);
 #endif
 
-#if (DEBUG & PHASE_SELECTION)
-      printk ("scsi%d : phase = SELECTION\n", hostno);
-#endif
+      DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n", hostno);
 
       clock = jiffies + ST0X_SELECTION_DELAY;
 
@@ -1012,33 +937,27 @@
  * 6.  Enable SCSI drivers and asserted SEL and ATTN
  */
 
-#if defined(ARBITRATE)
-      { unsigned long flags;
+#ifdef ARBITRATE
       save_flags (flags);
       cli ();
       WRITE_CONTROL (0);
       WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
       WRITE_CONTROL (CMD_START_ARB);
       restore_flags (flags);
-      }
-      while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
-             (jiffies < clock) && !st0x_aborted) ;
 
-      if (!(status_read & STAT_ARB_CMPL))
-      {
-#if (DEBUG & PHASE_SELECTION)
-        if (status_read & STAT_SEL)
-          printk ("scsi%d : arbitration lost\n", hostno);
-        else
-          printk ("scsi%d : arbitration timeout.\n", hostno);
-#endif
-        WRITE_CONTROL (BASE_CMD);
-        return retcode (DID_NO_CONNECT);
-      };
+      ULOOP( ST0X_SELECTION_DELAY * 10000 ) {
+	status_read = STATUS;
+	if (status_read & STAT_ARB_CMPL) break;
+	if (st0x_aborted)	/* FIXME: What? We are going to do something even after abort? */
+	   break;
+	if (TIMEOUT || (status_read & STAT_SEL)) {
+	  printk( "scsi%d : arbitration lost or timeout.\n", hostno );
+	  WRITE_CONTROL (BASE_CMD);
+	  return retcode (DID_NO_CONNECT);
+	}
+      }
 
-#if (DEBUG & PHASE_SELECTION)
-      printk ("scsi%d : arbitration complete\n", hostno);
-#endif
+      DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n", hostno);
 #endif
 
 /*
@@ -1053,81 +972,53 @@
  *    try this with a SCSI protocol or logic analyzer to see what is
  *    going on.
  */
+       tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
+       tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN : 0);
+
+       save_flags(flags);
+       cli();
 #ifdef OLDCNTDATASCEME
 #ifdef SWAPCNTDATA
-      { unsigned long flags;
-        save_flags(flags);
-	cli();
-      WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
-                     (reselect ? CMD_ATTN : 0));
-      WRITE_DATA ((unsigned char) ((1 << target) |
-                               (controller_type == SEAGATE ? 0x80 : 0x40)));
-	restore_flags(flags);
-      }
+       WRITE_CONTROL (tmp_control);
+       WRITE_DATA (tmp_data);
 #else
-      { unsigned long flags;
-      save_flags(flags);
-      cli ();
-      WRITE_DATA ((unsigned char) ((1 << target) |
-                               (controller_type == SEAGATE ? 0x80 : 0x40)));
-      WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
-                     (reselect ? CMD_ATTN : 0));
-      restore_flags (flags);
-      }
+       WRITE_DATA (tmp_data);
+       WRITE_CONTROL (tmp_control);
 #endif
 #else
-       tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE 
-? 0x80 : 0x40));
-       tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
-                (reselect ? CMD_ATTN : 0) | CMD_BSY;
-       WRITE_CONTROL(tmp_data);
-       WRITE_DATA(tmp_control);
-       tmp_control ^= CMD_BSY;
-       WRITE_CONTROL(tmp_control);
-#endif /* OLDCNTDATASCEME */
-      while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock)
-             && !st0x_aborted)
-#if 0 && (DEBUG & PHASE_SELECTION)
-      {
-        temp = clock - jiffies;
+       tmp_control ^= CMD_BSY;		/* This is guesswork. What used to be in driver	   */
+       WRITE_CONTROL (tmp_control);	/* could never work: it sent data into control	   */
+       WRITE_DATA (tmp_data);		/* register and control info into data. Hopefully  */
+       tmp_control ^= CMD_BSY;		/* fixed, but order of first two may be wrong.     */
+       WRITE_CONTROL (tmp_control);	                              /* -- pavel@ucw.cz   */
+#endif       
 
-        if (!(jiffies % 5))
-          printk ("seagate_st0x_timeout : %d            \r", temp);
-      }
-      printk ("Done.                                             \n");
-      printk ("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n",
-              hostno, status_read, temp, st0x_aborted);
-#else
-        ;
-#endif
 
-      if ((jiffies >= clock) && !(status_read & STAT_BSY))
-      {
-#if (DEBUG & PHASE_SELECTION)
-        printk ("scsi%d : NO CONNECT with target %d, status = %x \n",
-                hostno, target, STATUS);
-#endif
-        return retcode (DID_NO_CONNECT);
-      }
+       restore_flags (flags);
 
+       ULOOP( 250*1000 ) {
+	 if (st0x_aborted) {
 /*
  *    If we have been aborted, and we have a command in progress, IE the
  *      target still has BSY asserted, then we will reset the bus, and
  *      notify the midlevel driver to expect sense.
  */
 
-      if (st0x_aborted)
-      {
-        WRITE_CONTROL (BASE_CMD);
-        if (STATUS & STAT_BSY)
-        {
-          printk ("scsi%d : BST asserted after we've been aborted.\n",
-                  hostno);
-          seagate_st0x_reset (NULL, 0);
-          return retcode (DID_RESET);
-        }
-        return retcode (st0x_aborted);
-      }
+	   WRITE_CONTROL (BASE_CMD);
+	   if (STATUS & STAT_BSY) {
+	     printk ("scsi%d : BST asserted after we've been aborted.\n", hostno);
+	     seagate_st0x_reset (NULL, 0);
+	     return retcode (DID_RESET);
+	   }
+	   return retcode (st0x_aborted);
+	 }
+	 if (STATUS & STAT_BSY) break;
+	 if (TIMEOUT) {
+	   DPRINTK (PHASE_SELECTION, "scsi%d : NO CONNECT with target %d, stat = %x \n",
+		    hostno, target, STATUS);
+	   return retcode (DID_NO_CONNECT);
+	 }
+       }
 
 /* Establish current pointers.  Take into account scatter / gather */
 
@@ -1151,17 +1042,13 @@
       }
       else
       {
-#if (DEBUG & DEBUG_SG)
-        printk ("scsi%d : scatter gather not requested.\n", hostno);
-#endif
+        DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
         buffer = NULL;
         len = SCint->request_bufflen;
         data = (unsigned char *) SCint->request_buffer;
       }
 
-#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
-      printk ("scsi%d : len = %d\n", hostno, len);
-#endif
+      DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n", hostno, len);
 
       break;
 #ifdef LINKED
@@ -1205,9 +1092,7 @@
  *
  */
 
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
-  printk ("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
-#endif
+  DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 
   incommand = 1;
   transfersize = SCint->transfersize;
@@ -1271,12 +1156,10 @@
  * in word-sized chunks as fast as we can.
  */
 
-#ifdef FAST
           if (!len)
           {
 #if 0
-            printk ("scsi%d: underflow to target %d lun %d \n", hostno,
-                    target, lun);
+            printk ("scsi%d: underflow to target %d lun %d \n", hostno, target, lun);
             st0x_aborted = DID_ERROR;
             fast = 0;
 #endif
@@ -1290,11 +1173,10 @@
 #endif
             )
           {
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+            DPRINTK (DEBUG_FAST,
+		     "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
                     "         len = %d, data = %08x\n",
                   hostno, SCint->underflow, SCint->transfersize, len, data);
-#endif
 
 /* SJT: Start. Fast Write */
 #ifdef SEAGATE_USE_ASM
@@ -1332,13 +1214,11 @@
 /* SJT: End */
             len -= transfersize;
             data += transfersize;
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer complete len = %d data = %08x\n",
+            DPRINTK (DEBUG_FAST,
+		     "scsi%d : FAST transfer complete len = %d data = %08x\n",
                     hostno, len, data);
-#endif
           }
           else
-#endif /* ifdef FAST */
           {
 /*
  *    We loop as long as we are in a data out phase, there is data to send,
@@ -1404,15 +1284,14 @@
             ++buffer;
             len = buffer->length;
             data = (unsigned char *) buffer->address;
-#if (DEBUG & DEBUG_SG)
-            printk ("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+            DPRINTK (DEBUG_SG,
+		    "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
                     hostno, len, data);
-#endif
           }
           break;
 
         case REQ_DATAIN:
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
           if (borken)
           {
 #if (DEBUG & (PHASE_DATAIN))
@@ -1432,7 +1311,7 @@
           }
           else
 #endif
-#ifdef FAST
+
             if (fast && transfersize && !(len % transfersize) &&
                 (len >= transfersize)
 #ifdef FAST32
@@ -1440,11 +1319,11 @@
 #endif
             )
           {
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+            DPRINTK (DEBUG_FAST,
+		     "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
                     "         len = %d, data = %08x\n",
                   hostno, SCint->underflow, SCint->transfersize, len, data);
-#endif
+
 /* SJT: Start. Fast Read */
 #ifdef SEAGATE_USE_ASM
             __asm__(
@@ -1486,13 +1365,11 @@
             transfered += transfersize;
 #endif
 
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer complete len = %d data = %08x\n",
+            DPRINTK (DEBUG_FAST,
+		     "scsi%d : FAST transfer complete len = %d data = %08x\n",
                     hostno, len, data);
-#endif
           }
           else
-#endif
           {
 
 #if (DEBUG & PHASE_DATAIN)
@@ -1571,10 +1448,9 @@
             ++buffer;
             len = buffer->length;
             data = (unsigned char *) buffer->address;
-#if (DEBUG & DEBUG_SG)
-            printk ("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+            DPRINTK (DEBUG_SG, 
+		     "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
                     hostno, len, data);
-#endif
           }
 
           break;
@@ -1586,7 +1462,7 @@
             {
               WRITE_DATA (*(const unsigned char *) cmnd);
               cmnd = 1 + (const unsigned char *) cmnd;
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
               if (borken)
                 borken_wait ();
 #endif
@@ -1613,9 +1489,7 @@
             case CAN_RECONNECT:
               WRITE_DATA (IDENTIFY (1, lun));
 
-#if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
-              printk ("scsi%d : sent IDENTIFY message.\n", hostno);
-#endif
+              DPRINTK (PHASE_RESELECT | PHASE_MSGOUT, "scsi%d : sent IDENTIFY message.\n", hostno);
               break;
 #ifdef LINKED
             case LINKED_WRONG:
@@ -1623,13 +1497,10 @@
               linked_connected = 0;
               reselect = CAN_RECONNECT;
               goto connect_loop;
-#if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
-              printk ("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGOUT | DEBUG_LINKED, 
+		       "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
 #endif /* LINKED */
-#if (DEBUG & DEBUG_LINKED)
-              printk ("correct\n");
-#endif
+              DPRINTK (DEBUG_LINKED, "correct\n");
             default:
               WRITE_DATA (NOP);
               printk ("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
@@ -1640,6 +1511,7 @@
           switch (message = DATA)
           {
             case DISCONNECT:
+	      DANY ("seagate: deciding to disconnect\n");
               should_reconnect = 1;
               current_data = data;      /* WDE add */
               current_buffer = buffer;
@@ -1649,9 +1521,7 @@
               linked_connected = 0;
 #endif
               done = 1;
-#if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
-              printk ("scsi%d : disconnected.\n", hostno);
-#endif
+              DPRINTK ((PHASE_RESELECT | PHASE_MSGIN), "scsi%d : disconnected.\n", hostno);
               break;
 
 #ifdef LINKED
@@ -1662,15 +1532,11 @@
 /*
  * Note : we should check for underflow here.
  */
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : command complete.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : command complete.\n", hostno);
               done = 1;
               break;
             case ABORT:
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : abort message.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : abort message.\n", hostno);
               done = 1;
               break;
             case SAVE_POINTERS:
@@ -1678,9 +1544,7 @@
               current_bufflen = len;    /* WDE add */
               current_data = data;      /* WDE mod */
               current_nobuffs = nobuffs;
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : pointers saved.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : pointers saved.\n", hostno);
               break;
             case RESTORE_POINTERS:
               buffer = current_buffer;
@@ -1688,15 +1552,13 @@
               data = current_data;      /* WDE mod */
               len = current_bufflen;
               nobuffs = current_nobuffs;
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : pointers restored.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : pointers restored.\n", hostno);
               break;
             default:
 
 /*
  *    IDENTIFY distinguishes itself from the other messages by setting the
- *      high byte.
+ *      high byte. [FIXME: should not this read "the high bit"? - pavel@ucw.cz]
  *
  *      Note : we need to handle at least one outstanding command per LUN,
  *      and need to hash the SCSI command for that I_T_L nexus based on the
@@ -1705,10 +1567,8 @@
 
               if (message & 0x80)
               {
-#if (DEBUG & PHASE_MSGIN)
-                printk ("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
+                DPRINTK (PHASE_MSGIN, "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
                         hostno, target, message & 7);
-#endif
               }
               else
               {
@@ -1719,10 +1579,8 @@
  *      needs some serious restructuring first though.
  */
 
-#if (DEBUG & PHASE_MSGIN)
-                printk ("scsi%d : unknown message %d from target %d.\n",
-                        hostno, message, target);
-#endif
+                DPRINTK (PHASE_MSGIN, 
+			 "scsi%d : unknown message %d from target %d.\n", hostno, message, target);
               }
           }
           break;
@@ -1733,7 +1591,7 @@
       }                                 /* end of switch (status_read &
                                            REQ_MASK) */
 
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
 /*
  * I really don't care to deal with borken devices in each single
  * byte transfer case (ie, message in, message out, status), so
@@ -1747,9 +1605,8 @@
   }                                     /* while(((status_read = STATUS)...)
                                            ends */
 
-#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
-  printk ("scsi%d : Transfered %d bytes\n", hostno, transfered);
-#endif
+  DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT, 
+	   "scsi%d : Transfered %d bytes\n", hostno, transfered);
 
 #if (DEBUG & PHASE_EXIT)
 #if 0                                   /* Doesn't work for scatter/gather */
@@ -1797,10 +1654,8 @@
         linked_target = current_target;
         linked_lun = current_lun;
         linked_connected = 1;
-#if (DEBUG & DEBUG_LINKED)
-        printk ("scsi%d : keeping I_T_L nexus established for linked command.\n",
-                hostno);
-#endif
+	DPRINTK (DEBUG_LINKED, "scsi%d : keeping I_T_L nexus established"
+		 "for linked command.\n", hostno);
     /* We also will need to adjust status to accommodate intermediate
        conditions. */
         if ((status == INTERMEDIATE_GOOD) ||
@@ -1814,9 +1669,7 @@
  * and flake if things aren't right.
  */
       default:
-#if (DEBUG & DEBUG_LINKED)
-        printk ("scsi%d : closing I_T_L nexus.\n", hostno);
-#endif
+        DPRINTK (DEBUG_LINKED, "scsi%d : closing I_T_L nexus.\n", hostno);
         linked_connected = 0;
     }
   }
@@ -1824,10 +1677,8 @@
 
   if (should_reconnect)
   {
-#if (DEBUG & PHASE_RESELECT)
-    printk ("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
-            hostno);
-#endif
+    DPRINTK (PHASE_RESELECT, "scsi%d : exiting seagate_st0x_queue_command()"
+	     "with reconnect enabled.\n", hostno);
     WRITE_CONTROL (BASE_CMD | CMD_INTR);
   }
   else
@@ -1841,32 +1692,27 @@
   st0x_aborted = DID_ABORT;
   return SCSI_ABORT_PENDING;
 }
+#undef ULOOP
+#undef TIMEOUT
 
 /*
-   the seagate_st0x_reset function resets the SCSI bus */
+ * the seagate_st0x_reset function resets the SCSI bus 
+ */
 
 int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
-  unsigned clock;
-
 /* No timeouts - this command is going to fail because it was reset. */
-#ifdef DEBUG
-  printk ("In seagate_st0x_reset()\n");
-#endif
+  DANY ("scsi%d: Reseting bus... ", hostno );
 
 /* assert  RESET signal on SCSI bus.  */
   WRITE_CONTROL (BASE_CMD | CMD_RST);
-  clock = jiffies + 2;
 
-/* Wait.  */
-  while (jiffies < clock) ;
+  udelay( 20*1000 );
 
   WRITE_CONTROL (BASE_CMD);
   st0x_aborted = DID_RESET;
 
-#ifdef DEBUG
-  printk ("SCSI bus reset.\n");
-#endif
+  DANY ("done.\n");
   return SCSI_RESET_WAKEUP;
 }
 
--- clean/drivers/scsi/seagate.h	Thu Dec 25 12:40:20 1997
+++ linux/drivers/scsi/seagate.h	Thu Jul 30 22:51:51 1998
@@ -20,10 +20,6 @@
 const char *seagate_st0x_info(struct Scsi_Host *);
 int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
 
-#ifndef NULL
-	#define NULL 0
-#endif
-
 #include <linux/kdev_t.h>
 int seagate_st0x_biosparam(Disk *, kdev_t, int*);
 
--- clean/drivers/scsi/Makefile	Sun May 10 21:33:25 1998
+++ linux/drivers/scsi/Makefile	Fri Jul 31 22:13:11 1998
@@ -15,7 +15,8 @@
 
 CFLAGS_aha152x.o =   -DDEBUG_AHA152X -DAUTOCONF
 CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
-CFLAGS_seagate.o =   -DARBITRATE -DSLOW_HANDSHAKE -DFAST32 -DPARITY
+CFLAGS_seagate.o =   -DARBITRATE -DPARITY
+# -DSLOW_RATE=50 -DFAST32
 
 .SUFFIXES:
 .SUFFIXES: .c .o .h .a

-- 
I'm really pavel@atrey.karlin.mff.cuni.cz. 	   Pavel
Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.rutgers.edu

home help back first fref pref prev next nref lref last post