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
  9. seagate_st0x_biosparam

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

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