root/kernel/blk_drv/scsi/seagate.c

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

DEFINITIONS

This source file includes following definitions.
  1. seagate_st0x_detect
  2. seagate_st0x_info
  3. seagate_reconnect_intr
  4. seagate_st0x_queue_command
  5. seagate_st0x_command
  6. internal_command
  7. seagate_st0x_abort
  8. seagate_st0x_reset

   1 /*
   2  *      seagate.c Copyright (C) 1992 Drew Eckhardt 
   3  *      low level scsi driver for ST01/ST02 by
   4  *              Drew Eckhardt 
   5  *
   6  *      <drew@colorado.edu>
   7  */
   8 
   9 #include <linux/config.h>
  10 
  11 #if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x) 
  12 #include <asm/io.h>
  13 #include <asm/system.h>
  14 #include <linux/signal.h>
  15 #include <linux/sched.h>
  16 #include "../blk.h"
  17 #include "scsi.h"
  18 #include "hosts.h"
  19 #include "seagate.h"
  20 
  21 
  22 static int internal_command(unsigned char target, unsigned char lun,
  23                             const void *cmnd,
  24                          void *buff, int bufflen, int reselect);
  25 
  26 static int incommand;                   /*
  27                                                 set if arbitration has finished and we are 
  28                                                 in some command phase.
  29                                         */
  30 
  31 static void *base_address = NULL;       /*
  32                                                 Where the card ROM starts,
  33                                                 used to calculate memory mapped
  34                                                 register location.
  35                                         */
  36 static volatile int abort_confirm = 0;
  37 
  38 static volatile void *st0x_cr_sr;       /*
  39                                                 control register write,
  40                                                 status register read.
  41                                                 256 bytes in length.
  42 
  43                                                 Read is status of SCSI BUS,
  44                                                 as per STAT masks.
  45 
  46                                         */
  47 
  48 
  49 static volatile void *st0x_dr;         /*
  50                                                 data register, read write
  51                                                 256 bytes in length.
  52                                         */
  53 
  54 
  55 static volatile int st0x_aborted=0;     /* 
  56                                                 set when we are aborted, ie by a time out, etc.
  57                                         */
  58 
  59                                         /*
  60                                                 In theory, we have a nice auto
  61                                                 detect routine - but this 
  62                                                 overides it. 
  63                                         */
  64 static unsigned char controller_type;   /* set to SEAGATE for ST0x boards or FD for TMC-88x boards */
  65                         
  66 #define retcode(result) (((result) << 16) | (message << 8) | status)                    
  67 #define STATUS (*(unsigned char *) st0x_cr_sr)
  68 #define CONTROL STATUS 
  69 #define DATA (*(unsigned char *) st0x_dr)
  70 
  71 #ifndef OVERRIDE                
  72 static const char *  seagate_bases[] = {(char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, (char *) 0xce000, (char *) 0xce000,
  73                                         (char *) 0xdc000, (char *) 0xde000};
  74 typedef struct 
  75         {
  76         char *signature ;
  77         unsigned offset;
  78         unsigned length;
  79         unsigned char type;
  80         } Signature;
  81         
  82 static const Signature signatures[] = {
  83 #ifdef CONFIG_SCSI_SEAGATE
  84 {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
  85 
  86 /*
  87         The following two lines are NOT mistakes.  One detects 
  88         ROM revision 3.0.0, the other 3.2.  Since seagate
  89         has only one type of SCSI adapter, and this is not 
  90         going to change, the "SEAGATE" and "SCSI" together
  91         are probably "good enough"
  92 */
  93 
  94 {"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
  95 {"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
  96 
  97 /*
  98         This is for the Future Domain 88x series.  I've been told that
  99         the Seagate controllers are just repackages of these, and seeing
 100         early seagate BIOS bearing the Future Domain copyright,
 101         I believe it.
 102 */
 103 
 104 {"FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88",5,48, FD},
 105 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
 106 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
 107 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
 108 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FD},
 109 #endif
 110 }
 111 ;
 112 /*
 113         Note that the last signature handles BIOS revisions 3.0.0 and 
 114         3.2 - the real ID's are 
 115 
 116 SEAGATE SCSI BIOS REVISION 3.0.0
 117 SEAGATE SCSI BIOS REVISION 3.2
 118 
 119 */
 120 
 121 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
 122 #endif
 123 
 124 /*
 125  * hostno stores the hostnumber, as told to us by the init routine.
 126  */
 127 
 128 static int hostno = -1;
 129 static void seagate_reconnect_intr(int);
 130 
 131 int seagate_st0x_detect (int hostnum)
     /* [previous][next][first][last][top][bottom][index][help] */
 132         {
 133 #ifndef OVERRIDE
 134         int i,j;
 135 #endif
 136 static struct sigaction seagate_sigaction = {
 137         &seagate_reconnect_intr,
 138         0,
 139         SA_INTERRUPT,
 140         NULL
 141 };
 142 
 143 /*
 144  *      First, we try for the manual override.
 145  */
 146 #ifdef DEBUG 
 147         printk("Autodetecting seagate ST0x\n");
 148 #endif
 149         
 150         if (hostno != -1)
 151                 {
 152                 printk ("ERROR : seagate_st0x_detect() called twice.\n");
 153                 return 0;
 154                 }
 155         
 156         base_address = NULL;
 157 #ifdef OVERRIDE
 158         base_address = (void *) OVERRIDE;
 159 
 160 /* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
 161 #ifdef CONTROLLER
 162         controller_type = CONTROLLER;
 163 #else
 164 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
 165 #endif
 166 #ifdef DEBUG
 167         printk("Base address overridden to %x, controller type is %s\n",
 168                 base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
 169 #endif
 170 #else   
 171 /*
 172  *      To detect this card, we simply look for the signature
 173  *      from the BIOS version notice in all the possible locations
 174  *      of the ROM's.  This has a nice sideeffect of not trashing
 175  *      any register locations that might be used by something else.
 176  */
 177 
 178         for (i = 0; i < (sizeof (seagate_bases) / sizeof (char  * )); ++i)
 179                 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
 180                 if (!memcmp ((void *) (seagate_bases[i] +
 181                     signatures[j].offset), (void *) signatures[j].signature,
 182                     signatures[j].length)) {
 183                         base_address = (void *) seagate_bases[i];
 184                         controller_type = signatures[j].type;
 185                 }
 186  #endif
 187  
 188         if (base_address)
 189                 {
 190                 st0x_cr_sr =(void *) (((unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00)); 
 191                 st0x_dr = (void *) (((unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
 192 #ifdef DEBUG
 193                 printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
 194 #endif
 195 /*
 196  *      At all times, we will use IRQ 5.  
 197  */
 198                 hostno = hostnum;
 199                 if (irqaction(5, &seagate_sigaction)) {
 200                         printk("Unable to allocate IRQ5 for ST0x driver\n");
 201                         return 0;
 202                 }
 203                 return -1;
 204                 }
 205         else
 206                 {
 207 #ifdef DEBUG
 208                 printk("ST0x not detected.\n");
 209 #endif
 210                 return 0;
 211                 }
 212         }
 213          
 214 const char *seagate_st0x_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216         static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n"
 217 "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/07/24 06:27:38 root Exp root $\n";
 218         return buffer;
 219 }
 220 
 221 /*
 222  * These are our saved pointers for the outstanding command that is 
 223  * waiting for a reconnect
 224  */
 225 
 226 static unsigned char current_target, current_lun;
 227 static unsigned char *current_cmnd, *current_data;
 228 static int current_bufflen;
 229 static void (*done_fn)(Scsi_Cmnd *) = NULL;
 230 static Scsi_Cmnd * SCint = NULL;
 231 
 232 /*
 233  * These control whether or not disconnect / reconnect will be attempted,
 234  * or are being attempted.
 235  */
 236 
 237 #define NO_RECONNECT    0
 238 #define RECONNECT_NOW   1
 239 #define CAN_RECONNECT   2
 240 
 241 /*
 242  * This determines if we are expecting to reconnect or not.
 243  */
 244 
 245 static int should_reconnect = 0;
 246 
 247 /*
 248  * The seagate_reconnect_intr routine is called when a target reselects the 
 249  * host adapter.  This occurs on the interrupt triggered by the target 
 250  * asserting SEL.
 251  */
 252 
 253 static void seagate_reconnect_intr (int unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 254         {
 255         int temp;
 256         Scsi_Cmnd * SCtmp;
 257 
 258 /* enable all other interrupts. */      
 259         sti();
 260 #if (DEBUG & PHASE_RESELECT)
 261         printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
 262 #endif
 263 
 264         if (!should_reconnect)
 265             printk("scsi%d: unexpected interrupt.\n", hostno);
 266         else
 267                 {
 268                 should_reconnect = 0;
 269 
 270 #if (DEBUG & PHASE_RESELECT)
 271                 printk("scsi%d : internal_command("
 272                        "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno, 
 273                         current_target, current_data, current_bufflen);
 274 #endif
 275         
 276                 temp =  internal_command (current_target, current_lun,
 277                         current_cmnd, current_data, current_bufflen,
 278                         RECONNECT_NOW);
 279 
 280                 if (msg_byte(temp) != DISCONNECT)
 281                         {
 282                         if (done_fn)
 283                                 {
 284 #if (DEBUG & PHASE_RESELECT)
 285                                 printk("scsi%d : done_fn(%d,%08x)", hostno, 
 286                                 hostno, temp);
 287 #endif
 288                                 if(!SCint) panic("SCint == NULL in seagate");
 289                                 SCtmp = SCint;
 290                                 SCint = NULL;
 291                                 SCtmp->result = temp;
 292                                 done_fn (SCtmp);
 293                                 }
 294                         else
 295                                 printk("done_fn() not defined.\n");
 296                         }
 297                 }
 298         } 
 299 
 300 /* 
 301  * The seagate_st0x_queue_command() function provides a queued interface
 302  * to the seagate SCSI driver.  Basically, it just passes control onto the
 303  * seagate_command() function, after fixing it so that the done_fn()
 304  * is set to the one passed to the function.  We have to be very careful,
 305  * because there are some commands on some devices that do not disconnect,
 306  * and if we simply call the done_fn when the command is done then another
 307  * command is started and queue_command is called again...  We end up
 308  * overflowing the kernel stack, and this tends not to be such a good idea.
 309  */
 310 
 311 static int recursion_depth = 0;
 312 
 313 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
 314         {
 315         int result;
 316         Scsi_Cmnd * SCtmp;
 317 
 318         done_fn = done;
 319         current_target = SCpnt->target;
 320         current_lun = SCpnt->lun;
 321         (const void *) current_cmnd = SCpnt->cmnd;
 322         current_data = SCpnt->request_buffer;
 323         current_bufflen = SCpnt->request_bufflen;
 324         SCint = SCpnt;
 325         if(recursion_depth) {
 326           return 0;
 327         };
 328         recursion_depth++;
 329         do{
 330           
 331           result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
 332                                      SCint->request_bufflen, 
 333                                      CAN_RECONNECT);
 334           if (msg_byte(result) == DISCONNECT)  break;
 335           SCtmp = SCint;
 336           SCint = NULL;
 337           SCtmp->result = result;
 338           done_fn (SCtmp);
 339         } while(SCint);
 340         recursion_depth--;
 341         return 0;
 342       }
 343 
 344 int seagate_st0x_command (Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 345         {
 346         return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
 347                                  SCpnt->request_bufflen, 
 348                                  (int) NO_RECONNECT);
 349         }
 350         
 351 static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
     /* [previous][next][first][last][top][bottom][index][help] */
 352                          void *buff, int bufflen, int reselect)
 353         {
 354         int len;                        
 355         unsigned char *data;    
 356         int clock;                      
 357         int temp;
 358 
 359 
 360 #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))    
 361         int i;
 362 #endif
 363 
 364 #if (DEBUG & PHASE_ETC)
 365         int phase=0, newphase;
 366 #endif
 367 
 368         int done = 0;
 369         unsigned char status = 0;       
 370         unsigned char message = 0;
 371         register unsigned char status_read;
 372 
 373         len=bufflen;
 374         data=(unsigned char *) buff;
 375 
 376         incommand = 0;
 377         st0x_aborted = 0;
 378 
 379 #if (DEBUG & PRINT_COMMAND)
 380         printk ("scsi%d : target = %d, command = ", hostno, target);
 381         for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
 382                 printk("%02x ",  ((unsigned char *) cmnd)[i]);
 383         printk("\n");
 384 #endif
 385 
 386 #if (DEBUG & PHASE_RESELECT)
 387         switch (reselect)
 388         {
 389         case RECONNECT_NOW :
 390                 printk("scsi%d : reconnecting\n", hostno);
 391                 break;
 392         case CAN_RECONNECT :
 393                 printk("scsi%d : allowed to reconnect\n", hostno);
 394                 break;
 395         default :
 396                 printk("scsi%d : not allowed to reconnect\n", hostno);
 397         }
 398 #endif
 399         
 400 
 401         if (target == (controller_type == SEAGATE ? 7 : 6))
 402                 return DID_BAD_TARGET;
 403 
 404 /*
 405  *      We work it differently depending on if this is is "the first time,"
 406  *      or a reconnect.  If this is a reselct phase, then SEL will 
 407  *      be asserted, and we must skip selection / arbitration phases.
 408  */
 409 
 410         if (reselect == RECONNECT_NOW) 
 411                 {
 412 #if (DEBUG & PHASE_RESELECT)
 413                 printk("scsi%d : phase RESELECT \n", hostno);
 414 #endif
 415 
 416 /*
 417  *      At this point, we should find the logical or of our ID and the original
 418  *      target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
 419  *
 420  *      After ARBITRATION phase is completed, only SEL, BSY, and the 
 421  *      target ID are asserted.  A valid initator ID is not on the bus
 422  *      until IO is asserted, so we must wait for that.
 423  */
 424                 
 425                 for (clock = jiffies + 10, temp = 0; (jiffies < clock) &&
 426                      !(STATUS & STAT_IO););
 427                 
 428                 if (jiffies >= clock)
 429                         {
 430 #if (DEBUG & PHASE_RESELECT)
 431                         printk("scsi%d : RESELECT timed out while waiting for IO .\n",
 432                                 hostno);
 433 #endif
 434                         return (DID_BAD_INTR << 16);
 435                         }
 436 
 437 /* 
 438  *      After I/O is asserted by the target, we can read our ID and its
 439  *      ID off of the BUS.
 440  */
 441  
 442                 if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
 443                         {
 444 #if (DEBUG & PHASE_RESELECT)
 445                         printk("scsi%d : detected reconnect request to different target.\n" 
 446                                "\tData bus = %d\n", hostno, temp);
 447 #endif
 448                         return (DID_BAD_INTR << 16);
 449                         }
 450 
 451                 if (!(temp & (1 << current_target)))
 452                         {
 453                         printk("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
 454                                 hostno, temp);
 455                         return (DID_BAD_INTR << 16);
 456                         }
 457                 data=current_data;      /* WDE add */
 458                 cmnd=current_cmnd;      /* WDE add */
 459                 len=current_bufflen;    /* WDE add */
 460 
 461 /*
 462  *      We have determined that we have been selected.  At this point, 
 463  *      we must respond to the reselection by asserting BSY ourselves
 464  */
 465 
 466                 CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
 467 
 468 /*
 469  *      The target will drop SEL, and raise BSY, at which time we must drop
 470  *      BSY.
 471  */
 472 
 473                 for (clock = jiffies + 10; (jiffies < clock) &&  (STATUS & STAT_SEL););
 474 
 475                 if (jiffies >= clock)
 476                         { 
 477                         CONTROL = (BASE_CMD | CMD_INTR);
 478 #if (DEBUG & PHASE_RESELECT)
 479                         printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
 480                                 hostno);
 481 #endif
 482                         return (DID_BAD_INTR << 16);                             
 483                         }
 484 
 485                 CONTROL = BASE_CMD;
 486 
 487 /*
 488  *      At this point, we have connected with the target and can get 
 489  *      on with our lives.
 490  */      
 491                 }       
 492         else
 493                 {       
 494 #if (DEBUG & PHASE_BUS_FREE)
 495                 printk ("scsi%d : phase = BUS FREE \n", hostno);
 496 #endif
 497 
 498 /*
 499  *      BUS FREE PHASE
 500  *
 501  *      On entry, we make sure that the BUS is in a BUS FREE
 502  *      phase, by insuring that both BSY and SEL are low for
 503  *      at least one bus settle delay.  Several reads help
 504  *      eliminate wire glitch.
 505  */
 506 
 507                 clock = jiffies + ST0X_BUS_FREE_DELAY;  
 508 
 509                 while (((STATUS |  STATUS | STATUS) & 
 510                          (STAT_BSY | STAT_SEL)) && 
 511                          (!st0x_aborted) && (jiffies < clock));
 512 
 513                 if (jiffies > clock)
 514                         return retcode(DID_BUS_BUSY);
 515                 else if (st0x_aborted)
 516                         return retcode(st0x_aborted);
 517 
 518 /*
 519  *      Bus free has been detected, within BUS settle.  I used to 
 520  *      support an arbitration phase - however, on the Seagate, this 
 521  *      degraded performance by a factor > 10 - so it is no more.
 522  */
 523 
 524 /*
 525  *      SELECTION PHASE
 526  *
 527  *      Now, we select the disk, giving it the SCSI ID at data
 528  *      and a command of PARITY if necessary, and we raise SEL.
 529  */
 530 
 531 #if (DEBUG & PHASE_SELECTION)
 532                 printk("scsi%d : phase = SELECTION\n", hostno);
 533 #endif
 534 
 535                 clock = jiffies + ST0X_SELECTION_DELAY;
 536 
 537 /*
 538  *      If we wish to disconnect, we should request a MESSAGE OUT
 539  *      at this point.  Technically, ATTN should be raised before 
 540  *      SEL = true and BSY = false (from arbitration), but I think this 
 541  *      should do.
 542  */
 543                 if (reselect)
 544                         CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
 545                                 CMD_ATTN;
 546                 
 547 /*
 548  *      We must assert both our ID and our target's ID on the bus.
 549  */
 550                 DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
 551 
 552 /*
 553  *      If we are allowing ourselves to reconnect, then I will keep 
 554  *      ATTN raised so we get MSG OUT. 
 555  */ 
 556                 CONTROL =  BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | 
 557                         (reselect ? CMD_ATTN : 0);
 558 
 559 /*
 560  *      When the SCSI device decides that we're gawking at it, it will 
 561  *      respond by asserting BUSY on the bus.
 562  */
 563                 while (!((status_read = STATUS) & STAT_BSY) && 
 564                         (jiffies < clock) && !st0x_aborted)
 565 
 566 #if (DEBUG & PHASE_SELECTION)
 567                 {
 568                 temp = clock - jiffies;
 569 
 570                 if (!(jiffies % 5))
 571                         printk("seagate_st0x_timeout : %d            \r",temp);
 572         
 573                 }
 574                 printk("Done.                                             \n\r");
 575                 printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", 
 576                         hostno, status_read, temp, st0x_aborted);
 577 #else
 578                 ;
 579 #endif
 580         
 581 
 582                 if ((jiffies > clock)  || (!st0x_aborted && 
 583                         !(status_read & STAT_BSY)))
 584                         {
 585 #if (DEBUG & PHASE_SELECT)
 586                         printk ("scsi%d : NO CONNECT with target %d, status = %x \n", 
 587                                 hostno, target, STATUS);
 588 #endif
 589                         return retcode(DID_NO_CONNECT);
 590                         }
 591 
 592 /*
 593  *      If we have been aborted, and we have a command in progress, IE the 
 594  *      target still has BSY asserted, then we will reset the bus, and 
 595  *      notify the midlevel driver to expect sense.
 596  */
 597 
 598                 if (st0x_aborted)
 599                         {
 600                         CONTROL = BASE_CMD;
 601                         if (STATUS & STAT_BSY)
 602                                 {
 603                                 seagate_st0x_reset();
 604                                 return retcode(DID_RESET);
 605                                 }
 606                         return retcode(st0x_aborted);
 607                         }       
 608                 }
 609 
 610         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | 
 611                 ((reselect == CAN_RECONNECT) ? CMD_ATTN : 0) ;
 612         
 613 /*
 614  *      INFORMATION TRANSFER PHASE
 615  *
 616  *      The nasty looking read / write inline assembler loops we use for 
 617  *      DATAIN and DATAOUT phases are approximately 4-5 times as fast as 
 618  *      the 'C' versions - since we're moving 1024 bytes of data, this
 619  *      really adds up.
 620  */
 621 
 622 #if (DEBUG & PHASE_ETC)
 623         printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 624 #endif  
 625 
 626         incommand = 1;
 627 
 628 
 629 /*
 630  *      Now, we poll the device for status information,
 631  *      and handle any requests it makes.  Note that since we are unsure of 
 632  *      how much data will be flowing across the system, etc and cannot 
 633  *      make reasonable timeouts, that we will instead have the midlevel
 634  *      driver handle any timeouts that occur in this phase.
 635  */
 636 
 637         while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 
 638                 {
 639 #ifdef PARITY
 640                 if (status_read & STAT_PARITY)
 641                         {
 642                         done = 1;
 643                         st0x_aborted = DID_PARITY;
 644                         }       
 645 #endif
 646 
 647                 if (status_read & STAT_REQ)
 648                         {
 649 #if (DEBUG & PHASE_ETC)
 650                         if ((newphase = (status_read & REQ_MASK)) != phase)
 651                                 {
 652                                 phase = newphase;
 653                                 switch (phase)
 654                                 {
 655                                 case REQ_DATAOUT: 
 656                                         printk("scsi%d : phase = DATA OUT\n",
 657                                                 hostno); 
 658                                         break;
 659                                 case REQ_DATAIN : 
 660                                         printk("scsi%d : phase = DATA IN\n",
 661                                                 hostno); 
 662                                         break;
 663                                 case REQ_CMDOUT : 
 664                                         printk("scsi%d : phase = COMMAND OUT\n",
 665                                                 hostno); 
 666                                         break;
 667                                 case REQ_STATIN :
 668                                          printk("scsi%d : phase = STATUS IN\n",
 669                                                 hostno); 
 670                                         break;
 671                                 case REQ_MSGOUT :
 672                                         printk("scsi%d : phase = MESSAGE OUT\n",
 673                                                 hostno); 
 674                                         break;
 675                                 case REQ_MSGIN :
 676                                         printk("scsi%d : phase = MESSAGE IN\n",
 677                                                 hostno);
 678                                         break;
 679                                 default : 
 680                                         printk("scsi%d : phase = UNKNOWN\n",
 681                                                 hostno); 
 682                                         st0x_aborted = 1; 
 683                                         done = 1;
 684                                 }       
 685                                 }
 686 #endif
 687 
 688                 switch (status_read & REQ_MASK)
 689                 {                       
 690                 case REQ_DATAOUT : 
 691 
 692 /*
 693  *      We loop as long as we are in a data out phase, there is data to send, 
 694  *      and BSY is still active.
 695  */
 696                 __asm__ (
 697 
 698 /*
 699         Local variables : 
 700         len = ecx
 701         data = esi
 702         st0x_cr_sr = ebx
 703         st0x_dr =  edi
 704 
 705         Test for any data here at all.
 706 */
 707         "movl %0, %%esi\n"              /* local value of data */
 708         "\tmovl %1, %%ecx\n"            /* local value of len */        
 709         "\torl %%ecx, %%ecx
 710         jz 2f
 711 
 712         cld
 713 
 714         movl _st0x_cr_sr, %%ebx
 715         movl _st0x_dr, %%edi
 716         
 717 1:      movb (%%ebx), %%al\n"
 718 /*
 719         Test for BSY
 720 */
 721 
 722         "\ttest $1, %%al
 723         jz 2f\n"
 724 
 725 /*
 726         Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
 727 */
 728         "\ttest $0xe, %%al
 729         jnz 2f  \n"
 730 /*
 731         Test for REQ
 732 */      
 733         "\ttest $0x10, %%al
 734         jz 1b
 735         lodsb
 736         movb %%al, (%%edi) 
 737         loop 1b
 738 
 739 2: 
 740         movl %%esi, %2
 741         movl %%ecx, %3
 742                                                                         ":
 743 /* output */
 744 "=r" (data), "=r" (len) :
 745 /* input */
 746 "0" (data), "1" (len) :
 747 /* clobbered */
 748 "ebx", "ecx", "edi", "esi"); 
 749 
 750                         break;
 751 
 752                 case REQ_DATAIN : 
 753 /*
 754  *      We loop as long as we are in a data in phase, there is room to read, 
 755  *      and BSY is still active
 756  */
 757  
 758                         __asm__ (
 759 /*
 760         Local variables : 
 761         ecx = len
 762         edi = data
 763         esi = st0x_cr_sr
 764         ebx = st0x_dr
 765 
 766         Test for room to read
 767 */
 768 
 769         "movl %0, %%edi\n"              /* data */
 770         "\tmovl %1, %%ecx\n"            /* len */
 771         "\torl %%ecx, %%ecx
 772         jz 2f
 773 
 774         cld
 775         movl _st0x_cr_sr, %%esi
 776         movl _st0x_dr, %%ebx
 777 
 778 1:      movb (%%esi), %%al\n"
 779 /*
 780         Test for BSY
 781 */
 782 
 783         "\ttest $1, %%al 
 784         jz 2f\n"
 785 
 786 /*
 787         Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
 788 */
 789         "\tmovb $0xe, %%ah      
 790         andb %%al, %%ah
 791         cmpb $0x04, %%ah
 792         jne 2f\n"
 793                 
 794 /*
 795         Test for REQ
 796 */      
 797         "\ttest $0x10, %%al
 798         jz 1b
 799 
 800         movb (%%ebx), %%al      
 801         stosb   
 802         loop 1b
 803 
 804 2:      movl %%edi, %2\n"               /* data */
 805         "\tmovl %%ecx, %3\n"            /* len */
 806                                                                         :
 807 /* output */
 808 "=r" (data), "=r" (len) :
 809 /* input */
 810 "0" (data), "1" (len) :
 811 /* clobbered */
 812 "ebx", "ecx", "edi", "esi"); 
 813                         break;
 814 
 815                 case REQ_CMDOUT : 
 816                         while (((status_read = STATUS) & STAT_BSY) && 
 817                                ((status_read & REQ_MASK) == REQ_CMDOUT))
 818                                 if (status_read & STAT_REQ)
 819                                         DATA = *(unsigned char *) cmnd ++;
 820                         break;
 821         
 822                 case REQ_STATIN : 
 823                         status = DATA;
 824                         break;
 825                                 
 826                 case REQ_MSGOUT : 
 827 /*
 828  *      We can only have sent a MSG OUT if we requested to do this 
 829  *      by raising ATTN.  So, we must drop ATTN.
 830  */
 831 
 832                         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
 833 /*
 834  *      If we are reconecting, then we must send an IDENTIFY message in 
 835  *       response  to MSGOUT.
 836  */
 837                         if (reselect)
 838                                 {
 839                                 DATA = IDENTIFY(1, lun);
 840 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT)) 
 841                                 printk("scsi%d : sent IDENTIFY message.\n", hostno);
 842 #endif
 843                                 }
 844                         else  
 845                                 {
 846                                 DATA = MESSAGE_REJECT;
 847                                 
 848 #if (DEBUG & PHASE_MSGOUT)
 849                                 printk("scsi%d : sent MESSAGE REJECT message.\n", hostno);
 850 #endif
 851                                 }
 852                         break;
 853                                         
 854                 case REQ_MSGIN : 
 855                         switch (message = DATA)
 856                         {
 857                         case DISCONNECT :
 858                                 should_reconnect = 1;
 859                                 current_data = data;    /* WDE add */
 860                                 current_bufflen = len;  /* WDE add */
 861 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
 862                                 printk("scsi%d : disconnected.\n", hostno);
 863                                 done=1;
 864                                 break;
 865 #endif
 866                         case COMMAND_COMPLETE :
 867 #if (DEBUG & PHASE_MSGIN)       
 868                                 printk("scsi%d : command complete.\n", hostno);
 869                                 done=1;
 870                                 break;
 871 #endif
 872                         case ABORT :
 873 #if (DEBUG & PHASE_MSGIN)
 874                                 printk("scsi%d : abort message.\n", hostno);
 875 #endif
 876                                 done=1;
 877                                 break;
 878                         case SAVE_POINTERS :
 879                                 current_data = data;    /* WDE mod */
 880                                 current_bufflen = len;  /* WDE add */
 881 #if (DEBUG & PHASE_MSGIN)
 882                                 printk("scsi%d : pointers saved.\n", hostno);
 883 #endif 
 884                                 break;
 885                         case RESTORE_POINTERS:
 886                                 data=current_data;      /* WDE mod */
 887                                 cmnd=current_cmnd;
 888 #if (DEBUG & PHASE_MSGIN)
 889                                 printk("scsi%d : pointers restored.\n", hostno);
 890 #endif
 891                                 break;
 892                         default:
 893 
 894 /*
 895  *      IDENTIFY distinguishes itself from the other messages by setting the
 896  *      high byte.
 897  */
 898 
 899                                 if (message & 0x80)
 900                                         {
 901 #if (DEBUG & PHASE_MSGIN)
 902                                         printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
 903                                                 hostno, target, message & 7);
 904 #endif
 905                                         }       
 906                                 else
 907                                         {
 908                         
 909 #if (DEBUG & PHASE_MSGIN)
 910                                         printk("scsi%d : unknown message %d from target %d.\n",
 911                                                 hostno,  message,   target);
 912 #endif  
 913                                         }
 914                         }
 915                         break;
 916 
 917                 default : 
 918                         printk("scsi%d : unknown phase.\n", hostno); 
 919                         st0x_aborted = DID_ERROR; 
 920                 }       
 921                 } /* while ends */
 922                 } /* if ends */
 923 
 924 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
 925         printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);
 926 #endif
 927 
 928 #if (DEBUG & PHASE_EXIT)
 929         printk("Buffer : \n");
 930         for (i = 0; i < 20; ++i) 
 931                 printk ("%02x  ", ((unsigned char *) data)[i]); /* WDE mod */
 932         printk("\n");
 933         printk("Status = %02x, message = %02x\n", status, message);
 934 #endif
 935 
 936         
 937         if (st0x_aborted)
 938                 {
 939                 if (STATUS & STAT_BSY)
 940                         {
 941                         seagate_st0x_reset();
 942                         st0x_aborted = DID_RESET;
 943                         }
 944                 abort_confirm = 1;
 945                 }               
 946 
 947         if (should_reconnect)
 948                 {
 949 #if (DEBUG & PHASE_RESELECT)
 950                 printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
 951                         hostno);
 952 #endif
 953                 CONTROL = BASE_CMD | CMD_INTR ;
 954                 }
 955         else
 956                 CONTROL = BASE_CMD;
 957 
 958         return retcode (st0x_aborted);
 959         }
 960 
 961 int seagate_st0x_abort (Scsi_Cmnd * SCpnt, int code)
     /* [previous][next][first][last][top][bottom][index][help] */
 962         {
 963         if (code)
 964                 st0x_aborted = code;
 965         else
 966                 st0x_aborted = DID_ABORT;
 967 
 968                 return 0;
 969         }
 970 
 971 /*
 972         the seagate_st0x_reset function resets the SCSI bus
 973 */
 974         
 975 int seagate_st0x_reset (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 976         {
 977         unsigned clock;
 978         /*
 979                 No timeouts - this command is going to fail because 
 980                 it was reset.
 981         */
 982 
 983 #ifdef DEBUG
 984         printk("In seagate_st0x_reset()\n");
 985 #endif
 986 
 987 
 988         /* assert  RESET signal on SCSI bus.  */
 989                 
 990         CONTROL = BASE_CMD  | CMD_RST;
 991         clock=jiffies+2;
 992 
 993         
 994         /* Wait.  */
 995         
 996         while (jiffies < clock);
 997 
 998         CONTROL = BASE_CMD;
 999         
1000         st0x_aborted = DID_RESET;
1001 
1002 #ifdef DEBUG
1003         printk("SCSI bus reset.\n");
1004 #endif
1005         return 0;
1006         }
1007 
1008 #endif  
1009 

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