root/drivers/scsi/seagate.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st0x_setup
  2. tmc8xx_setup
  3. borken_init
  4. borken_wait
  5. seagate_st0x_detect
  6. seagate_st0x_info
  7. seagate_reconnect_intr
  8. seagate_st0x_queue_command
  9. seagate_st0x_command
  10. internal_command
  11. seagate_st0x_abort
  12. seagate_st0x_reset
  13. seagate_st0x_biosparam

   1 /*
   2  *      seagate.c Copyright (C) 1992, 1993 Drew Eckhardt 
   3  *      low level scsi driver for ST01/ST02, Future Domain TMC-885, 
   4  *      TMC-950  by
   5  *
   6  *              Drew Eckhardt 
   7  *
   8  *      <drew@colorado.edu>
   9  *
  10  *      Note : TMC-880 boards don't work because they have two bits in 
  11  *              the status register flipped, I'll fix this "RSN"
  12  *
  13  *      This card does all the I/O via memory mapped I/O, so there is no need
  14  *      to check or snarf a region of the I/O address space.
  15  */
  16 
  17 /*
  18  * Configuration : 
  19  * To use without BIOS -DOVERRIDE=base_address -DCONTROLLER=FD or SEAGATE
  20  * -DIRQ will override the default of 5.
  21  * Note: You can now set these options from the kernel's "command line".
  22  * The syntax is:
  23  *
  24  *     st0x=ADDRESS,IRQ                (for a Seagate controller)
  25  * or:
  26  *     tmc8xx=ADDRESS,IRQ              (for a TMC-8xx or TMC-950 controller)
  27  * eg:
  28  *     tmc8xx=0xC8000,15
  29  *
  30  * will configure the driver for a TMC-8xx style controller using IRQ 15
  31  * with a base address of 0xC8000.
  32  * 
  33  * -DFAST or -DFAST32 will use blind transfers where possible
  34  *
  35  * -DARBITRATE will cause the host adapter to arbitrate for the 
  36  *      bus for better SCSI-II compatibility, rather than just 
  37  *      waiting for BUS FREE and then doing its thing.  Should
  38  *      let us do one command per Lun when I integrate my 
  39  *      reorganization changes into the distribution sources.
  40  *
  41  * -DSLOW_HANDSHAKE will allow compatibility with broken devices that don't 
  42  *      handshake fast enough (ie, some CD ROM's) for the Seagate
  43  *      code.
  44  *
  45  * -DSLOW_RATE=x, x some number will let you specify a default 
  46  *      transfer rate if handshaking isn't working correctly.
  47  */
  48 
  49 #ifdef MODULE
  50 #include <linux/module.h>
  51 #endif
  52 
  53 #include <asm/io.h>
  54 #include <asm/system.h>
  55 #include <linux/signal.h>
  56 #include <linux/sched.h>
  57 #include <linux/string.h>
  58 #include <linux/config.h>
  59 #include <linux/proc_fs.h>
  60 
  61 #include "../block/blk.h"
  62 #include "scsi.h"
  63 #include "hosts.h"
  64 #include "seagate.h"
  65 #include "constants.h"
  66 
  67 
  68 #ifndef IRQ
  69 #define IRQ 5
  70 #endif
  71 
  72 #if (defined(FAST32) && !defined(FAST))
  73 #define FAST
  74 #endif
  75 
  76 #if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
  77 #define SLOW_HANDSHAKE
  78 #endif
  79 
  80 #if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
  81 #define SLOW_RATE 50
  82 #endif
  83 
  84 
  85 #if defined(LINKED)
  86 #undef LINKED           /* Linked commands are currently broken ! */
  87 #endif
  88 
  89 static int internal_command(unsigned char target, unsigned char lun,
  90                             const void *cmnd,
  91                          void *buff, int bufflen, int reselect);
  92 
  93 static int incommand;                   /*
  94                                                 set if arbitration has finished and we are 
  95                                                 in some command phase.
  96                                         */
  97 
  98 static void *base_address = NULL;       /*
  99                                                 Where the card ROM starts,
 100                                                 used to calculate memory mapped
 101                                                 register location.
 102                                         */
 103 #ifdef notyet
 104 static volatile int abort_confirm = 0;
 105 #endif
 106 
 107 static volatile void *st0x_cr_sr;       /*
 108                                                 control register write,
 109                                                 status register read.
 110                                                 256 bytes in length.
 111 
 112                                                 Read is status of SCSI BUS,
 113                                                 as per STAT masks.
 114 
 115                                         */
 116 
 117 
 118 static volatile void *st0x_dr;         /*
 119                                                 data register, read write
 120                                                 256 bytes in length.
 121                                         */
 122 
 123 
 124 static volatile int st0x_aborted=0;     /* 
 125                                                 set when we are aborted, ie by a time out, etc.
 126                                         */
 127 
 128 static unsigned char controller_type = 0; /* set to SEAGATE for ST0x boards or FD for TMC-8xx boards */
 129 static unsigned char irq = IRQ;
 130                         
 131 #define retcode(result) (((result) << 16) | (message << 8) | status)                    
 132 #define STATUS (*(volatile unsigned char *) st0x_cr_sr)
 133 #define CONTROL STATUS 
 134 #define DATA (*(volatile unsigned char *) st0x_dr)
 135 
 136 void st0x_setup (char *str, int *ints) {
     /* [previous][next][first][last][top][bottom][index][help] */
 137     controller_type = SEAGATE;
 138     base_address = (void *) ints[1];
 139     irq = ints[2];
 140 }
 141 
 142 void tmc8xx_setup (char *str, int *ints) {
     /* [previous][next][first][last][top][bottom][index][help] */
 143     controller_type = FD;
 144     base_address = (void *) ints[1];
 145     irq = ints[2];
 146 }
 147     
 148 
 149 #ifndef OVERRIDE                
 150 static const char *  seagate_bases[] = {
 151         (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
 152         (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
 153 };
 154 
 155 typedef struct {
 156         char *signature ;
 157         unsigned offset;
 158         unsigned length;
 159         unsigned char type;
 160 } Signature;
 161         
 162 static const Signature signatures[] = {
 163 #ifdef CONFIG_SCSI_SEAGATE
 164 {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
 165 {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 166 
 167 /*
 168  * The following two lines are NOT mistakes.  One detects ROM revision 
 169  * 3.0.0, the other 3.2.  Since seagate has only one type of SCSI adapter, 
 170  * and this is not going to change, the "SEAGATE" and "SCSI" together
 171  * are probably "good enough"
 172  */
 173 
 174 {"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
 175 {"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
 176 
 177 /*
 178  * However, future domain makes several incompatible SCSI boards, so specific
 179  * signatures must be used.
 180  */
 181 
 182 {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
 183 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
 184 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
 185 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
 186 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
 187 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FD},
 188 {"IBM F1 BIOS V1.1004/30/92",                      5, 25, FD},
 189 {"FUTURE DOMAIN TMC-950",                        5, 21, FD},
 190 #endif /* CONFIG_SCSI_SEAGATE */
 191 }
 192 ;
 193 
 194 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
 195 #endif /* n OVERRIDE */
 196 
 197 /*
 198  * hostno stores the hostnumber, as told to us by the init routine.
 199  */
 200 
 201 static int hostno = -1;
 202 static void seagate_reconnect_intr(int, struct pt_regs *);
 203 
 204 #ifdef FAST
 205 static int fast = 1;
 206 #endif 
 207 
 208 #ifdef SLOW_HANDSHAKE
 209 /* 
 210  * Support for broken devices : 
 211  * The Seagate board has a handshaking problem.  Namely, a lack 
 212  * thereof for slow devices.  You can blast 600K/second through 
 213  * it if you are polling for each byte, more if you do a blind 
 214  * transfer.  In the first case, with a fast device, REQ will 
 215  * transition high-low or high-low-high before your loop restarts 
 216  * and you'll have no problems.  In the second case, the board 
 217  * will insert wait states for up to 13.2 usecs for REQ to 
 218  * transition low->high, and everything will work.
 219  *
 220  * However, there's nothing in the state machine that says 
 221  * you *HAVE* to see a high-low-high set of transitions before
 222  * sending the next byte, and slow things like the Trantor CD ROMS
 223  * will break because of this.
 224  * 
 225  * So, we need to slow things down, which isn't as simple as it 
 226  * seems.  We can't slow things down period, because then people
 227  * who don't recompile their kernels will shoot me for ruining 
 228  * their performance.  We need to do it on a case per case basis.
 229  *
 230  * The best for performance will be to, only for borken devices 
 231  * (this is stored on a per-target basis in the scsi_devices array)
 232  * 
 233  * Wait for a low->high transition before continuing with that 
 234  * transfer.  If we timeout, continue anyways.  We don't need 
 235  * a long timeout, because REQ should only be asserted until the 
 236  * corresponding ACK is received and processed.
 237  *
 238  * Note that we can't use the system timer for this, because of 
 239  * resolution, and we *really* can't use the timer chip since 
 240  * gettimeofday() and the beeper routines use that.  So,
 241  * the best thing for us to do will be to calibrate a timing
 242  * loop in the initialization code using the timer chip before
 243  * gettimeofday() can screw with it.
 244  */
 245 
 246 static int borken_calibration = 0;
 247 static void borken_init (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 248   register int count = 0, start = jiffies + 1, stop = start + 25;
 249 
 250   while (jiffies < start);
 251   for (;jiffies < stop; ++count);
 252 
 253 /* 
 254  * Ok, we now have a count for .25 seconds.  Convert to a 
 255  * count per second and divide by transfer rate in K.
 256  */
 257 
 258   borken_calibration =  (count * 4) / (SLOW_RATE*1024);
 259 
 260   if (borken_calibration < 1)
 261         borken_calibration = 1;
 262 #if (DEBUG & DEBUG_BORKEN)
 263   printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n", 
 264         hostno, BORKEN_RATE, borken_calibration);
 265 #endif
 266 }
 267 
 268 static inline void borken_wait(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 269   register int count;
 270   for (count = borken_calibration; count && (STATUS & STAT_REQ); 
 271         --count);
 272 #if (DEBUG & DEBUG_BORKEN) 
 273   if (count)
 274         printk("scsi%d : borken timeout\n", hostno);
 275 #endif 
 276 }
 277 
 278 #endif /* def SLOW_HANDSHAKE */
 279 
 280 int seagate_st0x_detect (Scsi_Host_Template * tpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 281         {
 282      struct Scsi_Host *instance;
 283 #ifndef OVERRIDE
 284         int i,j;
 285 #endif 
 286 
 287 /*
 288  *      First, we try for the manual override.
 289  */
 290 #ifdef DEBUG 
 291         printk("Autodetecting ST0x / TMC-8xx\n");
 292 #endif
 293         
 294         if (hostno != -1)
 295                 {
 296                 printk ("ERROR : seagate_st0x_detect() called twice.\n");
 297                 return 0;
 298                 }
 299 
 300       /* If the user specified the controller type from the command line,
 301          controller_type will be non-zero, so don't try and detect one */
 302 
 303         if (!controller_type) {
 304 #ifdef OVERRIDE
 305         base_address = (void *) OVERRIDE;
 306 
 307 /* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
 308 #ifdef CONTROLLER
 309         controller_type = CONTROLLER;
 310 #else
 311 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
 312 #endif /* CONTROLLER */
 313 #ifdef DEBUG
 314         printk("Base address overridden to %x, controller type is %s\n",
 315                 base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
 316 #endif 
 317 #else /* OVERRIDE */    
 318 /*
 319  *      To detect this card, we simply look for the signature
 320  *      from the BIOS version notice in all the possible locations
 321  *      of the ROM's.  This has a nice side effect of not trashing
 322  *      any register locations that might be used by something else.
 323  *
 324  * XXX - note that we probably should be probing the address
 325  * space for the on-board RAM instead.
 326  */
 327 
 328         for (i = 0; i < (sizeof (seagate_bases) / sizeof (char  * )); ++i)
 329                 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
 330                 if (!memcmp ((void *) (seagate_bases[i] +
 331                     signatures[j].offset), (void *) signatures[j].signature,
 332                     signatures[j].length)) {
 333                         base_address = (void *) seagate_bases[i];
 334                         controller_type = signatures[j].type;
 335                 }
 336 #endif /* OVERRIDE */
 337         } /* (! controller_type) */
 338  
 339         tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
 340         tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
 341 
 342         if (base_address)
 343                 {
 344                 st0x_cr_sr =(void *) (((unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00)); 
 345                 st0x_dr = (void *) (((unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
 346 #ifdef DEBUG
 347                 printk("%s detected. Base address = %x, cr = %x, dr = %x\n", tpnt->name, base_address, st0x_cr_sr, st0x_dr);
 348 #endif
 349 /*
 350  *      At all times, we will use IRQ 5.  Should also check for IRQ3 if we 
 351  *      loose our first interrupt.
 352  */
 353                 instance = scsi_register(tpnt, 0);
 354                 hostno = instance->host_no;
 355                 if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT,
 356                    (controller_type == SEAGATE) ? "seagate" : "tmc-8xx")) {
 357                         printk("scsi%d : unable to allocate IRQ%d\n",
 358                                 hostno, (int) irq);
 359                         return 0;
 360                 }
 361 #ifdef SLOW_HANDSHAKE
 362                 borken_init();
 363 #endif
 364                 
 365                 printk("%s options:"
 366 #ifdef ARBITRATE
 367                 " ARBITRATE"
 368 #endif
 369 #ifdef SLOW_HANDSHAKE
 370                 " SLOW_HANDSHAKE"
 371 #endif
 372 #ifdef FAST
 373 #ifdef FAST32
 374                 " FAST32"
 375 #else
 376                 " FAST"
 377 #endif
 378 #endif
 379 #ifdef LINKED
 380                 " LINKED"
 381 #endif
 382               "\n", tpnt->name);
 383                 return 1;
 384                 }
 385         else
 386                 {
 387 #ifdef DEBUG
 388                 printk("ST0x / TMC-8xx not detected.\n");
 389 #endif
 390                 return 0;
 391                 }
 392         }
 393          
 394 const char *seagate_st0x_info(struct Scsi_Host * shpnt) {
     /* [previous][next][first][last][top][bottom][index][help] */
 395       static char buffer[64];
 396         sprintf(buffer, "%s at irq %d, address 0x%05X", 
 397                 (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
 398                 irq, (unsigned int)base_address);
 399         return buffer;
 400 }
 401 
 402 /*
 403  * These are our saved pointers for the outstanding command that is 
 404  * waiting for a reconnect
 405  */
 406 
 407 static unsigned char current_target, current_lun;
 408 static unsigned char *current_cmnd, *current_data;
 409 static int current_nobuffs;
 410 static struct scatterlist *current_buffer;
 411 static int current_bufflen;
 412 
 413 #ifdef LINKED
 414 
 415 /* 
 416  * linked_connected indicates whether or not we are currently connected to 
 417  * linked_target, linked_lun and in an INFORMATION TRANSFER phase,
 418  * using linked commands.
 419  */
 420 
 421 static int linked_connected = 0;
 422 static unsigned char linked_target, linked_lun;
 423 #endif
 424 
 425 
 426 static void (*done_fn)(Scsi_Cmnd *) = NULL;
 427 static Scsi_Cmnd * SCint = NULL;
 428 
 429 /*
 430  * These control whether or not disconnect / reconnect will be attempted,
 431  * or are being attempted.
 432  */
 433 
 434 #define NO_RECONNECT    0
 435 #define RECONNECT_NOW   1
 436 #define CAN_RECONNECT   2
 437 
 438 #ifdef LINKED
 439 
 440 /*
 441  * LINKED_RIGHT indicates that we are currently connected to the correct target
 442  * for this command, LINKED_WRONG indicates that we are connected to the wrong 
 443  * target.  Note that these imply CAN_RECONNECT.
 444  */
 445 
 446 #define LINKED_RIGHT    3
 447 #define LINKED_WRONG    4
 448 #endif
 449 
 450 /*
 451  * This determines if we are expecting to reconnect or not.
 452  */
 453 
 454 static int should_reconnect = 0;
 455 
 456 /*
 457  * The seagate_reconnect_intr routine is called when a target reselects the 
 458  * host adapter.  This occurs on the interrupt triggered by the target 
 459  * asserting SEL.
 460  */
 461 
 462 static void seagate_reconnect_intr(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 463         {
 464         int temp;
 465         Scsi_Cmnd * SCtmp;
 466 
 467 /* enable all other interrupts. */      
 468         sti();
 469 #if (DEBUG & PHASE_RESELECT)
 470         printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
 471 #endif
 472 
 473         if (!should_reconnect)
 474             printk("scsi%d: unexpected interrupt.\n", hostno);
 475         else {
 476                  should_reconnect = 0;
 477 
 478 #if (DEBUG & PHASE_RESELECT)
 479                 printk("scsi%d : internal_command("
 480                        "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno, 
 481                         current_target, current_data, current_bufflen);
 482 #endif
 483         
 484                 temp =  internal_command (current_target, current_lun,
 485                         current_cmnd, current_data, current_bufflen,
 486                         RECONNECT_NOW);
 487 
 488                 if (msg_byte(temp) != DISCONNECT) {
 489                         if (done_fn) {
 490 #if (DEBUG & PHASE_RESELECT)
 491                                 printk("scsi%d : done_fn(%d,%08x)", hostno, 
 492                                 hostno, temp);
 493 #endif
 494                                 if(!SCint) panic("SCint == NULL in seagate");
 495                                 SCtmp = SCint;
 496                                 SCint = NULL;
 497                                 SCtmp->result = temp;
 498                                 done_fn (SCtmp);
 499                         } else
 500                                 printk("done_fn() not defined.\n");
 501                         }
 502                 }
 503         } 
 504 
 505 /* 
 506  * The seagate_st0x_queue_command() function provides a queued interface
 507  * to the seagate SCSI driver.  Basically, it just passes control onto the
 508  * seagate_command() function, after fixing it so that the done_fn()
 509  * is set to the one passed to the function.  We have to be very careful,
 510  * because there are some commands on some devices that do not disconnect,
 511  * and if we simply call the done_fn when the command is done then another
 512  * command is started and queue_command is called again...  We end up
 513  * overflowing the kernel stack, and this tends not to be such a good idea.
 514  */
 515 
 516 static int recursion_depth = 0;
 517 
 518 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
 519         {
 520         int result, reconnect;
 521         Scsi_Cmnd * SCtmp;
 522 
 523         done_fn = done;
 524         current_target = SCpnt->target;
 525         current_lun = SCpnt->lun;
 526         (const void *) current_cmnd = SCpnt->cmnd;
 527         current_data = (unsigned char *) SCpnt->request_buffer;
 528         current_bufflen = SCpnt->request_bufflen;
 529         SCint = SCpnt;
 530         if(recursion_depth) {
 531           return 0;
 532         };
 533         recursion_depth++;
 534         do{
 535 #ifdef LINKED
 536 /*
 537  * Set linked command bit in control field of SCSI command.
 538  */
 539 
 540           current_cmnd[SCpnt->cmd_len] |= 0x01;
 541           if (linked_connected) {
 542 #if (DEBUG & DEBUG_LINKED) 
 543             printk("scsi%d : using linked commands, current I_T_L nexus is ",
 544               hostno);
 545 #endif
 546             if ((linked_target == current_target) && 
 547               (linked_lun == current_lun)) {
 548 #if (DEBUG & DEBUG_LINKED) 
 549             printk("correct\n");
 550 #endif
 551               reconnect = LINKED_RIGHT;
 552             } else {
 553 #if (DEBUG & DEBUG_LINKED) 
 554             printk("incorrect\n");
 555 #endif
 556               reconnect = LINKED_WRONG;
 557             }
 558           } else 
 559 #endif /* LINKED */
 560             reconnect = CAN_RECONNECT;
 561 
 562 
 563 
 564 
 565 
 566           result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
 567                                      SCint->request_bufflen, 
 568                                      reconnect);
 569           if (msg_byte(result) == DISCONNECT)  break;
 570           SCtmp = SCint;
 571           SCint = NULL;
 572           SCtmp->result = result;
 573           done_fn (SCtmp);
 574         } while(SCint);
 575         recursion_depth--;
 576         return 0;
 577       }
 578 
 579 int seagate_st0x_command (Scsi_Cmnd * SCpnt) {
     /* [previous][next][first][last][top][bottom][index][help] */
 580         return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
 581                                  SCpnt->request_bufflen, 
 582                                  (int) NO_RECONNECT);
 583 }
 584         
 585 static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
     /* [previous][next][first][last][top][bottom][index][help] */
 586                          void *buff, int bufflen, int reselect) {
 587         int len = 0;
 588         unsigned char *data = NULL;     
 589         struct scatterlist *buffer = NULL;
 590         int nobuffs = 0;
 591         int clock;                      
 592         int temp;
 593 #ifdef SLOW_HANDSHAKE
 594         int borken;     /* Does the current target require Very Slow I/O ? */
 595 #endif
 596 
 597 
 598 #if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT) 
 599         int transfered = 0;
 600 #endif
 601 
 602 #if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
 603         (DEBUG & PHASE_EXIT))   
 604         int i;
 605 #endif
 606 
 607 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
 608         int phase=0, newphase;
 609 #endif
 610 
 611         int done = 0;
 612         unsigned char status = 0;       
 613         unsigned char message = 0;
 614         register unsigned char status_read;
 615 
 616         unsigned transfersize = 0, underflow = 0;
 617 
 618         incommand = 0;
 619         st0x_aborted = 0;
 620 
 621 #ifdef SLOW_HANDSHAKE
 622         borken = (int) SCint->device->borken;
 623 #endif
 624 
 625 #if (DEBUG & PRINT_COMMAND)
 626         printk ("scsi%d : target = %d, command = ", hostno, target);
 627         print_command((unsigned char *) cmnd);
 628         printk("\n");
 629 #endif
 630 
 631 #if (DEBUG & PHASE_RESELECT)
 632         switch (reselect) {
 633         case RECONNECT_NOW :
 634                 printk("scsi%d : reconnecting\n", hostno);
 635                 break;
 636 #ifdef LINKED
 637         case LINKED_RIGHT : 
 638                 printk("scsi%d : connected, can reconnect\n", hostno);
 639                 break;
 640         case LINKED_WRONG :
 641                 printk("scsi%d : connected to wrong target, can reconnect\n",
 642                         hostno);
 643                 break;          
 644 #endif
 645         case CAN_RECONNECT :
 646                 printk("scsi%d : allowed to reconnect\n", hostno);
 647                 break;
 648         default :
 649                 printk("scsi%d : not allowed to reconnect\n", hostno);
 650         }
 651 #endif
 652         
 653 
 654         if (target == (controller_type == SEAGATE ? 7 : 6))
 655                 return DID_BAD_TARGET;
 656 
 657 /*
 658  *      We work it differently depending on if this is is "the first time,"
 659  *      or a reconnect.  If this is a reselect phase, then SEL will 
 660  *      be asserted, and we must skip selection / arbitration phases.
 661  */
 662 
 663         switch (reselect) {
 664         case RECONNECT_NOW:
 665 #if (DEBUG & PHASE_RESELECT)
 666                 printk("scsi%d : phase RESELECT \n", hostno);
 667 #endif
 668 
 669 /*
 670  *      At this point, we should find the logical or of our ID and the original
 671  *      target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
 672  *
 673  *      After ARBITRATION phase is completed, only SEL, BSY, and the 
 674  *      target ID are asserted.  A valid initiator ID is not on the bus
 675  *      until IO is asserted, so we must wait for that.
 676  */
 677                 clock = jiffies + 10;
 678                 for (;;) {
 679                         temp = STATUS;
 680                         if ((temp & STAT_IO) && !(temp & STAT_BSY))
 681                                 break;
 682 
 683                         if (jiffies > clock) {
 684 #if (DEBUG & PHASE_RESELECT)
 685                                 printk("scsi%d : RESELECT timed out while waiting for IO .\n",
 686                                         hostno);
 687 #endif
 688                                 return (DID_BAD_INTR << 16);
 689                         }
 690                 }
 691 
 692 /* 
 693  *      After I/O is asserted by the target, we can read our ID and its
 694  *      ID off of the BUS.
 695  */
 696  
 697                 if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
 698                         {
 699 #if (DEBUG & PHASE_RESELECT)
 700                         printk("scsi%d : detected reconnect request to different target.\n" 
 701                                "\tData bus = %d\n", hostno, temp);
 702 #endif
 703                         return (DID_BAD_INTR << 16);
 704                         }
 705 
 706                 if (!(temp & (1 << current_target)))
 707                         {
 708                         printk("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
 709                                 hostno, temp);
 710                         return (DID_BAD_INTR << 16);
 711                         }
 712 
 713                 buffer=current_buffer;  
 714                 cmnd=current_cmnd;      /* WDE add */
 715                 data=current_data;      /* WDE add */
 716                 len=current_bufflen;    /* WDE add */
 717                 nobuffs=current_nobuffs;
 718 
 719 /*
 720  *      We have determined that we have been selected.  At this point, 
 721  *      we must respond to the reselection by asserting BSY ourselves
 722  */
 723 
 724 #if 1
 725                 CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
 726 #else
 727                 CONTROL = (BASE_CMD | CMD_BSY);
 728 #endif
 729 
 730 /*
 731  *      The target will drop SEL, and raise BSY, at which time we must drop
 732  *      BSY.
 733  */
 734 
 735                 for (clock = jiffies + 10; (jiffies < clock) &&  (STATUS & STAT_SEL););
 736 
 737                 if (jiffies >= clock)
 738                         { 
 739                         CONTROL = (BASE_CMD | CMD_INTR);
 740 #if (DEBUG & PHASE_RESELECT)
 741                         printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
 742                                 hostno);
 743 #endif
 744                         return (DID_BAD_INTR << 16);                             
 745                         }
 746 
 747                 CONTROL = BASE_CMD;
 748 
 749 /*
 750  *      At this point, we have connected with the target and can get 
 751  *      on with our lives.
 752  */      
 753                 break;
 754         case CAN_RECONNECT:
 755 
 756 #ifdef LINKED
 757 /*
 758  * This is a bletcherous hack, just as bad as the Unix #! interpreter stuff.
 759  * If it turns out we are using the wrong I_T_L nexus, the easiest way to deal
 760  * with it is to go into our INFORMATION TRANSFER PHASE code, send a ABORT 
 761  * message on MESSAGE OUT phase, and then loop back to here.
 762  */
 763   
 764 connect_loop :
 765 
 766 #endif
 767 
 768 #if (DEBUG & PHASE_BUS_FREE)
 769                 printk ("scsi%d : phase = BUS FREE \n", hostno);
 770 #endif
 771 
 772 /*
 773  *      BUS FREE PHASE
 774  *
 775  *      On entry, we make sure that the BUS is in a BUS FREE
 776  *      phase, by insuring that both BSY and SEL are low for
 777  *      at least one bus settle delay.  Several reads help
 778  *      eliminate wire glitch.
 779  */
 780 
 781                 clock = jiffies + ST0X_BUS_FREE_DELAY;  
 782 
 783 #if !defined (ARBITRATE) 
 784                 while (((STATUS |  STATUS | STATUS) & 
 785                          (STAT_BSY | STAT_SEL)) && 
 786                          (!st0x_aborted) && (jiffies < clock));
 787 
 788                 if (jiffies > clock)
 789                         return retcode(DID_BUS_BUSY);
 790                 else if (st0x_aborted)
 791                         return retcode(st0x_aborted);
 792 #endif
 793 
 794 #if (DEBUG & PHASE_SELECTION)
 795                 printk("scsi%d : phase = SELECTION\n", hostno);
 796 #endif
 797 
 798                 clock = jiffies + ST0X_SELECTION_DELAY;
 799 
 800 /*
 801  * Arbitration/selection procedure : 
 802  * 1.  Disable drivers
 803  * 2.  Write HOST adapter address bit
 804  * 3.  Set start arbitration.
 805  * 4.  We get either ARBITRATION COMPLETE or SELECT at this
 806  *     point.
 807  * 5.  OR our ID and targets on bus.
 808  * 6.  Enable SCSI drivers and asserted SEL and ATTN
 809  */
 810                 
 811 #if defined(ARBITRATE)  
 812         cli();
 813         CONTROL = 0;
 814         DATA = (controller_type == SEAGATE) ? 0x80 : 0x40;
 815         CONTROL = CMD_START_ARB; 
 816         sti();
 817         while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
 818                 (jiffies < clock) && !st0x_aborted);
 819 
 820         if (!(status_read & STAT_ARB_CMPL)) {
 821 #if (DEBUG & PHASE_SELECTION)
 822                 if (status_read & STAT_SEL) 
 823                         printk("scsi%d : arbitration lost\n", hostno);
 824                 else
 825                         printk("scsi%d : arbitration timeout.\n", hostno);
 826 #endif
 827                 CONTROL = BASE_CMD;
 828                 return retcode(DID_NO_CONNECT);
 829         };
 830 
 831 #if (DEBUG & PHASE_SELECTION)
 832         printk("scsi%d : arbitration complete\n", hostno);
 833 #endif
 834 #endif
 835 
 836 
 837 /*
 838  *      When the SCSI device decides that we're gawking at it, it will 
 839  *      respond by asserting BUSY on the bus.
 840  *
 841  *      Note : the Seagate ST-01/02 product manual says that we should 
 842  *      twiddle the DATA register before the control register.  However,
 843  *      this does not work reliably so we do it the other way around.
 844  *
 845  *      Probably could be a problem with arbitration too, we really should
 846  *      try this with a SCSI protocol or logic analyzer to see what is 
 847  *      going on.
 848  */
 849         cli();
 850         DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
 851         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | 
 852                 (reselect ? CMD_ATTN : 0);
 853         sti();
 854                 while (!((status_read = STATUS) & STAT_BSY) && 
 855                         (jiffies < clock) && !st0x_aborted)
 856 
 857 #if 0 && (DEBUG & PHASE_SELECTION)
 858                 {
 859                 temp = clock - jiffies;
 860 
 861                 if (!(jiffies % 5))
 862                         printk("seagate_st0x_timeout : %d            \r",temp);
 863         
 864                 }
 865                 printk("Done.                                             \n");
 866                 printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", 
 867                         hostno, status_read, temp, st0x_aborted);
 868 #else
 869                 ;
 870 #endif
 871         
 872 
 873                 if ((jiffies >= clock)  && !(status_read & STAT_BSY))
 874                         {
 875 #if (DEBUG & PHASE_SELECTION)
 876                         printk ("scsi%d : NO CONNECT with target %d, status = %x \n", 
 877                                 hostno, target, STATUS);
 878 #endif
 879                         return retcode(DID_NO_CONNECT);
 880                         }
 881 
 882 /*
 883  *      If we have been aborted, and we have a command in progress, IE the 
 884  *      target still has BSY asserted, then we will reset the bus, and 
 885  *      notify the midlevel driver to expect sense.
 886  */
 887 
 888                 if (st0x_aborted) {
 889                         CONTROL = BASE_CMD;
 890                         if (STATUS & STAT_BSY) {
 891                                 printk("scsi%d : BST asserted after we've been aborted.\n",
 892                                         hostno);
 893                                 seagate_st0x_reset(NULL);
 894                                 return retcode(DID_RESET);
 895                         }
 896                         return retcode(st0x_aborted);
 897                 }       
 898 
 899 /* Establish current pointers.  Take into account scatter / gather */
 900 
 901         if ((nobuffs = SCint->use_sg)) {
 902 #if (DEBUG & DEBUG_SG)
 903         {
 904         int i;
 905         printk("scsi%d : scatter gather requested, using %d buffers.\n",
 906                 hostno, nobuffs);
 907         for (i = 0; i < nobuffs; ++i)
 908                 printk("scsi%d : buffer %d address = %08x length = %d\n",
 909                         hostno, i, buffer[i].address, buffer[i].length);
 910         }
 911 #endif
 912                 
 913                 buffer = (struct scatterlist *) SCint->buffer;
 914                 len = buffer->length;
 915                 data = (unsigned char *) buffer->address;
 916         } else {
 917 #if (DEBUG & DEBUG_SG)
 918         printk("scsi%d : scatter gather not requested.\n", hostno);
 919 #endif
 920                 buffer = NULL;
 921                 len = SCint->request_bufflen;
 922                 data = (unsigned char *) SCint->request_buffer;
 923         }
 924 
 925 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
 926         printk("scsi%d : len = %d\n", hostno, len);
 927 #endif
 928 
 929                 break;
 930 #ifdef LINKED
 931         case LINKED_RIGHT:
 932                 break;
 933         case LINKED_WRONG:
 934                 break;
 935 #endif
 936         }
 937 
 938 /*
 939  *      There are several conditions under which we wish to send a message : 
 940  *      1.  When we are allowing disconnect / reconnect, and need to establish
 941  *          the I_T_L nexus via an IDENTIFY with the DiscPriv bit set.
 942  *
 943  *      2.  When we are doing linked commands, are have the wrong I_T_L nexus
 944  *          established and want to send an ABORT message.
 945  */
 946 
 947         
 948         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | 
 949                 (((reselect == CAN_RECONNECT)
 950 #ifdef LINKED 
 951                 || (reselect == LINKED_WRONG)
 952 #endif 
 953                 )  ? CMD_ATTN : 0) ;
 954         
 955 /*
 956  *      INFORMATION TRANSFER PHASE
 957  *
 958  *      The nasty looking read / write inline assembler loops we use for 
 959  *      DATAIN and DATAOUT phases are approximately 4-5 times as fast as 
 960  *      the 'C' versions - since we're moving 1024 bytes of data, this
 961  *      really adds up.
 962  */
 963 
 964 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
 965         printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 966 #endif  
 967 
 968         incommand = 1;
 969         transfersize = SCint->transfersize;
 970         underflow = SCint->underflow;
 971 
 972 
 973 /*
 974  *      Now, we poll the device for status information,
 975  *      and handle any requests it makes.  Note that since we are unsure of 
 976  *      how much data will be flowing across the system, etc and cannot 
 977  *      make reasonable timeouts, that we will instead have the midlevel
 978  *      driver handle any timeouts that occur in this phase.
 979  */
 980 
 981         while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 
 982                 {
 983 #ifdef PARITY
 984                 if (status_read & STAT_PARITY)
 985                         {
 986                         printk("scsi%d : got parity error\n", hostno);
 987                         st0x_aborted = DID_PARITY;
 988                         }       
 989 #endif
 990 
 991                 if (status_read & STAT_REQ)
 992                         {
 993 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
 994                         if ((newphase = (status_read & REQ_MASK)) != phase)
 995                                 {
 996                                 phase = newphase;
 997                                 switch (phase)
 998                                 {
 999                                 case REQ_DATAOUT: 
1000                                         printk("scsi%d : phase = DATA OUT\n",
1001                                                 hostno); 
1002                                         break;
1003                                 case REQ_DATAIN : 
1004                                         printk("scsi%d : phase = DATA IN\n",
1005                                                 hostno); 
1006                                         break;
1007                                 case REQ_CMDOUT : 
1008                                         printk("scsi%d : phase = COMMAND OUT\n",
1009                                                 hostno); 
1010                                         break;
1011                                 case REQ_STATIN :
1012                                          printk("scsi%d : phase = STATUS IN\n",
1013                                                 hostno); 
1014                                         break;
1015                                 case REQ_MSGOUT :
1016                                         printk("scsi%d : phase = MESSAGE OUT\n",
1017                                                 hostno); 
1018                                         break;
1019                                 case REQ_MSGIN :
1020                                         printk("scsi%d : phase = MESSAGE IN\n",
1021                                                 hostno);
1022                                         break;
1023                                 default : 
1024                                         printk("scsi%d : phase = UNKNOWN\n",
1025                                                 hostno); 
1026                                         st0x_aborted = DID_ERROR; 
1027                                 }       
1028                                 }
1029 #endif
1030                 switch (status_read & REQ_MASK)
1031                 {                       
1032                 case REQ_DATAOUT : 
1033 /*
1034  * If we are in fast mode, then we simply splat the data out
1035  * in word-sized chunks as fast as we can.
1036  */
1037 
1038 #ifdef FAST 
1039 if (!len) {
1040 #if 0 
1041         printk("scsi%d: underflow to target %d lun %d \n", 
1042                 hostno, target, lun);
1043         st0x_aborted = DID_ERROR;
1044         fast = 0;
1045 #endif
1046         break;
1047 }
1048 
1049 if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
1050 #ifdef FAST32
1051         && !(transfersize % 4)
1052 #endif
1053         ) {
1054 #if (DEBUG & DEBUG_FAST) 
1055         printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
1056                "         len = %d, data = %08x\n", hostno, SCint->underflow, 
1057                SCint->transfersize, len, data);
1058 #endif
1059 
1060         __asm__("
1061         cld;
1062 "
1063 #ifdef FAST32
1064 "       shr $2, %%ecx;
1065 1:      lodsl;
1066         movl %%eax, (%%edi);
1067 "
1068 #else
1069 "1:     lodsb;
1070         movb %%al, (%%edi);
1071 "
1072 #endif
1073 "       loop 1b;" : :
1074         /* input */
1075         "D" (st0x_dr), "S" (data), "c" (SCint->transfersize) :
1076         /* clobbered */
1077         "eax", "ecx", "esi" );
1078 
1079         len -= transfersize;
1080         data += transfersize;
1081 
1082 #if (DEBUG & DEBUG_FAST)
1083         printk("scsi%d : FAST transfer complete len = %d data = %08x\n", 
1084                 hostno, len, data);
1085 #endif
1086 
1087 
1088 } else 
1089 #endif
1090 
1091 {
1092 /*
1093  *      We loop as long as we are in a data out phase, there is data to send, 
1094  *      and BSY is still active.
1095  */
1096                 __asm__ (
1097 
1098 /*
1099         Local variables : 
1100         len = ecx
1101         data = esi
1102         st0x_cr_sr = ebx
1103         st0x_dr =  edi
1104 
1105         Test for any data here at all.
1106 */
1107         "\torl %%ecx, %%ecx
1108         jz 2f
1109 
1110         cld
1111 
1112         movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx
1113         movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi
1114         
1115 1:      movb (%%ebx), %%al\n"
1116 /*
1117         Test for BSY
1118 */
1119 
1120         "\ttest $1, %%al
1121         jz 2f\n"
1122 
1123 /*
1124         Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
1125 */
1126         "\ttest $0xe, %%al
1127         jnz 2f  \n"
1128 /*
1129         Test for REQ
1130 */      
1131         "\ttest $0x10, %%al
1132         jz 1b
1133         lodsb
1134         movb %%al, (%%edi) 
1135         loop 1b
1136 
1137 2: 
1138                                                                         ":
1139 /* output */
1140 "=S" (data), "=c" (len) :
1141 /* input */
1142 "0" (data), "1" (len) :
1143 /* clobbered */
1144 "eax", "ebx", "edi"); 
1145 }
1146 
1147                         if (!len && nobuffs) {
1148                                 --nobuffs;
1149                                 ++buffer;
1150                                 len = buffer->length;
1151                                 data = (unsigned char *) buffer->address;
1152 #if (DEBUG & DEBUG_SG)
1153         printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
1154                 hostno, len, data);
1155 #endif
1156                         }
1157                         break;
1158 
1159                 case REQ_DATAIN : 
1160 #ifdef SLOW_HANDSHAKE
1161         if (borken) {
1162 #if (DEBUG & (PHASE_DATAIN))
1163                 transfered += len;
1164 #endif
1165                 for (; len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
1166                         STAT_REQ); --len) {
1167                                 *data++ = DATA;
1168                                 borken_wait();
1169 }
1170 #if (DEBUG & (PHASE_DATAIN))
1171                 transfered -= len;
1172 #endif
1173         } else
1174 #endif
1175 #ifdef FAST
1176 if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
1177 #ifdef FAST32
1178         && !(transfersize % 4)
1179 #endif
1180         ) {
1181 #if (DEBUG & DEBUG_FAST) 
1182         printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
1183                "         len = %d, data = %08x\n", hostno, SCint->underflow, 
1184                SCint->transfersize, len, data);
1185 #endif
1186         __asm__("
1187         cld;
1188 "
1189 #ifdef FAST32
1190 "       shr $2, %%ecx;
1191 1:      movl (%%esi), %%eax;
1192         stosl;
1193 "
1194 #else
1195 "1:     movb (%%esi), %%al;
1196         stosb;
1197 "
1198 #endif
1199 
1200 "       loop 1b;" : :
1201         /* input */
1202         "S" (st0x_dr), "D" (data), "c" (SCint->transfersize) :
1203         /* clobbered */
1204         "eax", "ecx", "edi");
1205 
1206         len -= transfersize;
1207         data += transfersize;
1208 
1209 #if (DEBUG & PHASE_DATAIN)
1210         printk("scsi%d: transfered += %d\n", hostno, transfersize);
1211         transfered += transfersize;
1212 #endif
1213 
1214 #if (DEBUG & DEBUG_FAST)
1215         printk("scsi%d : FAST transfer complete len = %d data = %08x\n", 
1216                 hostno, len, data);
1217 #endif
1218 
1219 } else
1220 #endif
1221 {
1222 
1223 #if (DEBUG & PHASE_DATAIN)
1224         printk("scsi%d: transfered += %d\n", hostno, len);
1225         transfered += len;      /* Assume we'll transfer it all, then
1226                                    subtract what we *didn't* transfer */
1227 #endif
1228         
1229 /*
1230  *      We loop as long as we are in a data in phase, there is room to read, 
1231  *      and BSY is still active
1232  */
1233  
1234                         __asm__ (
1235 /*
1236         Local variables : 
1237         ecx = len
1238         edi = data
1239         esi = st0x_cr_sr
1240         ebx = st0x_dr
1241 
1242         Test for room to read
1243 */
1244         "\torl %%ecx, %%ecx
1245         jz 2f
1246 
1247         cld
1248         movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi
1249         movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx
1250 
1251 1:      movb (%%esi), %%al\n"
1252 /*
1253         Test for BSY
1254 */
1255 
1256         "\ttest $1, %%al 
1257         jz 2f\n"
1258 
1259 /*
1260         Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
1261 */
1262         "\tmovb $0xe, %%ah      
1263         andb %%al, %%ah
1264         cmpb $0x04, %%ah
1265         jne 2f\n"
1266                 
1267 /*
1268         Test for REQ
1269 */      
1270         "\ttest $0x10, %%al
1271         jz 1b
1272 
1273         movb (%%ebx), %%al      
1274         stosb   
1275         loop 1b\n"
1276 
1277 "2:\n"
1278                                                                         :
1279 /* output */
1280 "=D" (data), "=c" (len) :
1281 /* input */
1282 "0" (data), "1" (len) :
1283 /* clobbered */
1284 "eax","ebx", "esi"); 
1285 
1286 #if (DEBUG & PHASE_DATAIN)
1287         printk("scsi%d: transfered -= %d\n", hostno, len);
1288         transfered -= len;              /* Since we assumed all of Len got 
1289                                          * transfered, correct our mistake */
1290 #endif
1291 }
1292         
1293                         if (!len && nobuffs) {
1294                                 --nobuffs;
1295                                 ++buffer;
1296                                 len = buffer->length;
1297                                 data = (unsigned char *) buffer->address;
1298 #if (DEBUG & DEBUG_SG)
1299         printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
1300                 hostno, len, data);
1301 #endif
1302                         }
1303 
1304                         break;
1305 
1306                 case REQ_CMDOUT : 
1307                         while (((status_read = STATUS) & STAT_BSY) && 
1308                                ((status_read & REQ_MASK) == REQ_CMDOUT))
1309                                 if (status_read & STAT_REQ) {
1310                                         DATA = *(unsigned char *) cmnd;
1311                                         cmnd = 1+(unsigned char *) cmnd;
1312 #ifdef SLOW_HANDSHAKE
1313                                         if (borken) 
1314                                                 borken_wait();
1315 #endif
1316                                 }
1317                         break;
1318         
1319                 case REQ_STATIN : 
1320                         status = DATA;
1321                         break;
1322                                 
1323                 case REQ_MSGOUT : 
1324 /*
1325  *      We can only have sent a MSG OUT if we requested to do this 
1326  *      by raising ATTN.  So, we must drop ATTN.
1327  */
1328 
1329                         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
1330 /*
1331  *      If we are reconnecting, then we must send an IDENTIFY message in 
1332  *       response  to MSGOUT.
1333  */
1334                         switch (reselect) {
1335                         case CAN_RECONNECT:
1336                                 DATA = IDENTIFY(1, lun);
1337 
1338 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT)) 
1339                                 printk("scsi%d : sent IDENTIFY message.\n", hostno);
1340 #endif
1341                                 break;
1342 #ifdef LINKED
1343                         case LINKED_WRONG:
1344                                 DATA = ABORT;
1345                                 linked_connected = 0;
1346                                 reselect = CAN_RECONNECT;
1347                                 goto connect_loop;
1348 #if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
1349                                 printk("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
1350 #endif
1351 #endif /* LINKED */
1352 #if (DEBUG & DEBUG_LINKED) 
1353             printk("correct\n");
1354 #endif
1355                         default:
1356                                 DATA = NOP;
1357                                 printk("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
1358                         }
1359                         break;
1360                                         
1361                 case REQ_MSGIN : 
1362                         switch (message = DATA) {
1363                         case DISCONNECT :
1364                                 should_reconnect = 1;
1365                                 current_data = data;    /* WDE add */
1366                                 current_buffer = buffer;
1367                                 current_bufflen = len;  /* WDE add */
1368                                 current_nobuffs = nobuffs;
1369 #ifdef LINKED
1370                                 linked_connected = 0;
1371 #endif
1372                                 done=1;
1373 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
1374                                 printk("scsi%d : disconnected.\n", hostno);
1375 #endif
1376                                 break;
1377 
1378 #ifdef LINKED
1379                         case LINKED_CMD_COMPLETE:
1380                         case LINKED_FLG_CMD_COMPLETE:
1381 #endif
1382                         case COMMAND_COMPLETE :
1383 /*
1384  * Note : we should check for underflow here.   
1385  */
1386 #if (DEBUG & PHASE_MSGIN)       
1387                                 printk("scsi%d : command complete.\n", hostno);
1388 #endif
1389                                 done = 1;
1390                                 break;
1391                         case ABORT :
1392 #if (DEBUG & PHASE_MSGIN)
1393                                 printk("scsi%d : abort message.\n", hostno);
1394 #endif
1395                                 done=1;
1396                                 break;
1397                         case SAVE_POINTERS :
1398                                 current_buffer = buffer;
1399                                 current_bufflen = len;  /* WDE add */
1400                                 current_data = data;    /* WDE mod */
1401                                 current_nobuffs = nobuffs;
1402 #if (DEBUG & PHASE_MSGIN)
1403                                 printk("scsi%d : pointers saved.\n", hostno);
1404 #endif 
1405                                 break;
1406                         case RESTORE_POINTERS:
1407                                 buffer=current_buffer;
1408                                 cmnd=current_cmnd;
1409                                 data=current_data;      /* WDE mod */
1410                                 len=current_bufflen;
1411                                 nobuffs=current_nobuffs;
1412 #if (DEBUG & PHASE_MSGIN)
1413                                 printk("scsi%d : pointers restored.\n", hostno);
1414 #endif
1415                                 break;
1416                         default:
1417 
1418 /*
1419  *      IDENTIFY distinguishes itself from the other messages by setting the
1420  *      high byte.
1421  *      
1422  *      Note : we need to handle at least one outstanding command per LUN,
1423  *      and need to hash the SCSI command for that I_T_L nexus based on the 
1424  *      known ID (at this point) and LUN.
1425  */
1426 
1427                                 if (message & 0x80) {
1428 #if (DEBUG & PHASE_MSGIN)
1429                                         printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
1430                                                 hostno, target, message & 7);
1431 #endif
1432                                 } else {
1433 
1434 /*
1435  *      We should go into a MESSAGE OUT phase, and send  a MESSAGE_REJECT 
1436  *      if we run into a message that we don't like.  The seagate driver 
1437  *      needs some serious restructuring first though.
1438  */
1439 
1440 #if (DEBUG & PHASE_MSGIN)
1441                                         printk("scsi%d : unknown message %d from target %d.\n",
1442                                                 hostno,  message,   target);
1443 #endif  
1444                                 }
1445                         }
1446                         break;
1447 
1448                 default : 
1449                         printk("scsi%d : unknown phase.\n", hostno); 
1450                         st0x_aborted = DID_ERROR; 
1451                 }       
1452 
1453 #ifdef SLOW_HANDSHAKE
1454 /*
1455  * I really don't care to deal with borken devices in each single 
1456  * byte transfer case (ie, message in, message out, status), so
1457  * I'll do the wait here if necessary.
1458  */
1459                 if (borken)
1460                         borken_wait();
1461 #endif
1462  
1463                 } /* if ends */
1464                 } /* while ends */
1465 
1466 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
1467         printk("scsi%d : Transfered %d bytes\n", hostno, transfered);
1468 #endif
1469 
1470 #if (DEBUG & PHASE_EXIT)
1471 #if 0           /* Doesn't work for scatter / gather */
1472         printk("Buffer : \n");
1473         for (i = 0; i < 20; ++i) 
1474                 printk ("%02x  ", ((unsigned char *) data)[i]); /* WDE mod */
1475         printk("\n");
1476 #endif
1477         printk("scsi%d : status = ", hostno);
1478         print_status(status);
1479         printk("message = %02x\n", message);
1480 #endif
1481 
1482 
1483 /* We shouldn't reach this until *after* BSY has been deasserted */
1484 #ifdef notyet
1485         if (st0x_aborted) {
1486                 if (STATUS & STAT_BSY) {        
1487                         seagate_st0x_reset(NULL);
1488                         st0x_aborted = DID_RESET;
1489                 } 
1490                 abort_confirm = 1;
1491         } 
1492 #endif
1493 
1494 #ifdef LINKED
1495 else {
1496 /*
1497  * Fix the message byte so that unsuspecting high level drivers don't 
1498  * puke when they see a LINKED COMMAND message in place of the COMMAND 
1499  * COMPLETE they may be expecting.  Shouldn't be necessary, but it's 
1500  * better to be on the safe side. 
1501  *
1502  * A non LINKED* message byte will indicate that the command completed, 
1503  * and we are now disconnected.
1504  */
1505 
1506                 switch (message) {
1507                 case LINKED_CMD_COMPLETE :
1508                 case LINKED_FLG_CMD_COMPLETE : 
1509                         message = COMMAND_COMPLETE;
1510                         linked_target = current_target;
1511                         linked_lun = current_lun;
1512                         linked_connected = 1;
1513 #if (DEBUG & DEBUG_LINKED)
1514                         printk("scsi%d : keeping I_T_L nexus established for linked command.\n", 
1515                                 hostno);
1516 #endif
1517 /*
1518  * We also will need to adjust status to accommodate intermediate conditions.
1519  */
1520                         if ((status == INTERMEDIATE_GOOD) ||
1521                                 (status == INTERMEDIATE_C_GOOD))
1522                                 status = GOOD;
1523                         
1524                         break;
1525 /*
1526  * We should also handle what are "normal" termination messages 
1527  * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually, 
1528  * and flake if things aren't right.
1529  */
1530 
1531                 default :
1532 #if (DEBUG & DEBUG_LINKED)
1533                         printk("scsi%d : closing I_T_L nexus.\n", hostno);
1534 #endif
1535                         linked_connected = 0;
1536                 }
1537         }
1538 #endif /* LINKED */
1539 
1540 
1541 
1542 
1543         if (should_reconnect) {
1544 #if (DEBUG & PHASE_RESELECT)
1545                 printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
1546                         hostno);
1547 #endif
1548                 CONTROL = BASE_CMD | CMD_INTR ;
1549         } else 
1550                 CONTROL = BASE_CMD;
1551 
1552         return retcode (st0x_aborted);
1553         }
1554 
1555 int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1556         {
1557           st0x_aborted = DID_ABORT;
1558           
1559           return SCSI_ABORT_PENDING;
1560         }
1561 
1562 /*
1563         the seagate_st0x_reset function resets the SCSI bus
1564 */
1565         
1566 int seagate_st0x_reset (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1567         {
1568         unsigned clock;
1569         /*
1570                 No timeouts - this command is going to fail because 
1571                 it was reset.
1572         */
1573 
1574 #ifdef DEBUG
1575         printk("In seagate_st0x_reset()\n");
1576 #endif
1577 
1578 
1579         /* assert  RESET signal on SCSI bus.  */
1580                 
1581         CONTROL = BASE_CMD  | CMD_RST;
1582         clock=jiffies+2;
1583 
1584         
1585         /* Wait.  */
1586         
1587         while (jiffies < clock);
1588 
1589         CONTROL = BASE_CMD;
1590         
1591         st0x_aborted = DID_RESET;
1592 
1593 #ifdef DEBUG
1594         printk("SCSI bus reset.\n");
1595 #endif
1596         return SCSI_RESET_WAKEUP;
1597         }
1598 
1599 #include <asm/segment.h>
1600 #include "sd.h"
1601 #include "scsi_ioctl.h"
1602 
1603 int seagate_st0x_biosparam(Disk * disk, int dev, int* ip) {
     /* [previous][next][first][last][top][bottom][index][help] */
1604   unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page;
1605   int *sizes, result, formatted_sectors, total_sectors;
1606   int cylinders, heads, sectors;
1607 
1608 /*
1609  * Only SCSI-I CCS drives and later implement the necessary mode sense 
1610  * pages.  
1611  */
1612 
1613   if (disk->device->scsi_level < 2) 
1614         return -1;
1615 
1616   sizes = (int *) buf;
1617   data = (unsigned char *) (sizes + 2);
1618 
1619   cmd[0] = MODE_SENSE;
1620   cmd[1] = (disk->device->lun << 5) & 0xe5;
1621   cmd[2] = 0x04; /* Read page 4, rigid disk geometry page current values */
1622   cmd[3] = 0;
1623   cmd[4] = 255;
1624   cmd[5] = 0;
1625 
1626 /*
1627  * We are transferring 0 bytes in the out direction, and expect to get back
1628  * 24 bytes for each mode page.
1629  */
1630 
1631   sizes[0] = 0;
1632   sizes[1] = 256;
1633 
1634   memcpy (data, cmd, 6);
1635 
1636   if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
1637 /*
1638  * The mode page lies beyond the MODE SENSE header, with length 4, and 
1639  * the BLOCK DESCRIPTOR, with length header[3].
1640  */
1641 
1642     page = data + 4 + data[3];
1643     heads = (int) page[5];
1644     cylinders = (page[2] << 16) | (page[3] << 8) | page[4];
1645 
1646     cmd[2] = 0x03; /* Read page 3, format page current values */
1647     memcpy (data, cmd, 6);
1648 
1649     if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
1650       page = data + 4 + data[3];
1651       sectors = (page[10] << 8) | page[11];     
1652 
1653         
1654 /*
1655  * Get the total number of formatted sectors from the block descriptor, 
1656  * so we can tell how many are being used for alternates.  
1657  */
1658 
1659       formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8) |
1660         data[4 + 3] ;
1661 
1662       total_sectors = (heads * cylinders * sectors);
1663 
1664 /*
1665  * Adjust the real geometry by subtracting 
1666  * (spare sectors / (heads * tracks)) cylinders from the number of cylinders.
1667  *
1668  * It appears that the CE cylinder CAN be a partial cylinder.
1669  */
1670 
1671      
1672 printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n",
1673     hostno, heads, cylinders, sectors, total_sectors, formatted_sectors);
1674 
1675       if (!heads || !sectors || !cylinders)
1676         result = -1;
1677       else
1678         cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors));
1679 
1680 /*
1681  * Now, we need to do a sanity check on the geometry to see if it is 
1682  * BIOS compatible.  The maximum BIOS geometry is 1024 cylinders * 
1683  * 256 heads * 64 sectors. 
1684  */
1685 
1686       if ((cylinders > 1024) || (sectors > 64)) 
1687         result = -1;
1688       else {
1689         ip[0] = heads;
1690         ip[1] = sectors;
1691         ip[2] = cylinders;
1692       }
1693 
1694 /* 
1695  * There should be an alternate mapping for things the seagate doesn't
1696  * understand, but I couldn't say what it is with reasonable certainty.
1697  */
1698 
1699       }
1700     }
1701     
1702   return result;
1703 }
1704 
1705 #ifdef MODULE
1706 /* Eventually this will go into an include file, but this will be later */
1707 Scsi_Host_Template driver_template = SEAGATE_ST0X;
1708 
1709 #include "scsi_module.c"
1710 #endif

/* [previous][next][first][last][top][bottom][index][help] */