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

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