patch-2.1.118 linux/drivers/scsi/seagate.c

Next file: linux/drivers/scsi/seagate.h
Previous file: linux/drivers/scsi/sd.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.117/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
@@ -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>
  */
 
 /*
@@ -50,7 +43,7 @@
  *      let us do one command per Lun when I integrate my
  *      reorganization changes into the distribution sources.
  *
- * -DDEBUG
+ * -DDEBUG=65535
  *      Will activate debug code.
  *
  * -DFAST or -DFAST32 
@@ -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,25 @@
 #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)
+#else
+#define DPRINTK( when, msg... ) do { } while (0)
+#endif
+#define DANY( msg... ) DPRINTK( 0xffff, msg );
 
 static struct proc_dir_entry proc_scsi_seagate =
 {
@@ -118,24 +119,16 @@
 #define IRQ 5
 #endif
 
-#if (defined(FAST32) && !defined(FAST))
+#ifdef FAST32
 #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
+#undef LINKED		/* Linked commands are currently broken! */
 
-#if defined(LINKED)
-#undef LINKED                           /* Linked commands are currently
-                                           broken! */
+#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
 		driver, and Mitsugu Suzuki for information on the ST-01
@@ -206,7 +199,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 +216,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
 
@@ -242,10 +233,6 @@
 static unsigned int base_address = 0;   /* Where the card ROM starts, used to 
                                            calculate memory mapped register
                                            location.  */
-#ifdef notyet
-static volatile int abort_confirm = 0;
-
-#endif
 
 static unsigned long st0x_cr_sr;        /* control register write, status
                                            register read.  256 bytes in
@@ -262,15 +249,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 +287,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 +315,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 +330,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 +370,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 +385,47 @@
 
 /*
  * 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 */
+
+/* These beasts only live on ISA, and ISA means 8MHz. Each ULOOP()
+ * contains at least one ISA access, which takes more than 0.125
+ * usec. So if we loop 8 times time in usec, we are safe.
+ */
+
+#define ULOOP( i ) for (clock = i*8;;)
+#define TIMEOUT (!(clock--))
 
-int seagate_st0x_detect (Scsi_Host_Template * tpnt)
+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
+ *    First, we try for the manual override.  */
+  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 +436,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 +466,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 +513,9 @@
             " DEBUG"
 #endif
 #ifdef FAST
-#ifdef FAST32
-            " FAST32"
-#else
             " FAST"
+#ifdef FAST32
+            "32"
 #endif
 #endif
 #ifdef LINKED
@@ -542,8 +527,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 +536,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 +562,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 +570,6 @@
 
 static int linked_connected = 0;
 static unsigned char linked_target, linked_lun;
-
 #endif
 
 static void (*done_fn) (Scsi_Cmnd *) = NULL;
@@ -609,17 +584,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 +605,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 +614,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 +627,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 +638,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;
@@ -707,6 +671,7 @@
   int result, reconnect;
   Scsi_Cmnd *SCtmp;
 
+  DANY( "seagate: que_command" );
   done_fn = done;
   current_target = SCpnt->target;
   current_lun = SCpnt->lun;
@@ -714,10 +679,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 +691,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 +709,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 +729,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 +792,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 +802,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 +821,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 +856,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 +887,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 +898,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 +912,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 +927,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 +962,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 +1032,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 +1082,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 +1146,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 +1163,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 +1204,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 +1274,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 +1301,7 @@
           }
           else
 #endif
-#ifdef FAST
+
             if (fast && transfersize && !(len % transfersize) &&
                 (len >= transfersize)
 #ifdef FAST32
@@ -1440,11 +1309,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 +1355,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 +1438,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 +1452,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 +1479,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 +1487,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 +1501,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 +1511,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 +1522,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 +1534,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 +1542,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 +1557,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 +1569,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 +1581,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 +1595,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 */
@@ -1764,17 +1611,6 @@
 #endif
 
 /* We shouldn't reach this until *after* BSY has been deasserted */
-#ifdef notyet
-  if (st0x_aborted)
-  {
-    if (STATUS & STAT_BSY)
-    {
-      seagate_st0x_reset (NULL);
-      st0x_aborted = DID_RESET;
-    }
-    abort_confirm = 1;
-  }
-#endif
 
 #ifdef LINKED
   else
@@ -1797,10 +1633,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 +1648,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 +1656,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 +1671,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;
 }
 

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