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

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