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

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