This source file includes following definitions.
- st0x_setup
 
- tmc8xx_setup
 
- borken_init
 
- borken_wait
 
- seagate_st0x_detect
 
- seagate_st0x_info
 
- seagate_reconnect_intr
 
- seagate_st0x_queue_command
 
- seagate_st0x_command
 
- internal_command
 
- seagate_st0x_abort
 
- seagate_st0x_reset
 
- seagate_st0x_biosparam
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 #include <linux/config.h>
  50 
  51 #if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_8xx) 
  52 #include <asm/io.h>
  53 #include <asm/system.h>
  54 #include <linux/signal.h>
  55 #include <linux/sched.h>
  56 #include <linux/string.h>
  57 #include "../block/blk.h"
  58 #include "scsi.h"
  59 #include "hosts.h"
  60 #include "seagate.h"
  61 #include "constants.h"
  62 
  63 
  64 #ifndef IRQ
  65 #define IRQ 5
  66 #endif
  67 
  68 #if (defined(FAST32) && !defined(FAST))
  69 #define FAST
  70 #endif
  71 
  72 #if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
  73 #define SLOW_HANDSHAKE
  74 #endif
  75 
  76 #if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
  77 #define SLOW_RATE 50
  78 #endif
  79 
  80 
  81 #if defined(LINKED)
  82 #undef LINKED           
  83 #endif
  84 
  85 static int internal_command(unsigned char target, unsigned char lun,
  86                             const void *cmnd,
  87                          void *buff, int bufflen, int reselect);
  88 
  89 static int incommand;                   
  90 
  91 
  92 
  93 
  94 static void *base_address = NULL;       
  95 
  96 
  97 
  98 
  99 static volatile int abort_confirm = 0;
 100 
 101 static volatile void *st0x_cr_sr;       
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 static volatile void *st0x_dr;         
 113 
 114 
 115 
 116 
 117 
 118 static volatile int st0x_aborted=0;     
 119 
 120 
 121 
 122 static unsigned char controller_type = 0; 
 123 static unsigned char irq = IRQ;
 124                         
 125 #define retcode(result) (((result) << 16) | (message << 8) | status)                    
 126 #define STATUS (*(volatile unsigned char *) st0x_cr_sr)
 127 #define CONTROL STATUS 
 128 #define DATA (*(volatile unsigned char *) st0x_dr)
 129 
 130 void st0x_setup (char *str, int *ints) {
     
 131     controller_type = SEAGATE;
 132     base_address = (void *) ints[1];
 133     irq = ints[2];
 134 }
 135 
 136 void tmc8xx_setup (char *str, int *ints) {
     
 137     controller_type = FD;
 138     base_address = (void *) ints[1];
 139     irq = ints[2];
 140 }
 141     
 142 
 143 #ifndef OVERRIDE                
 144 static const char *  seagate_bases[] = {
 145         (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
 146         (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
 147 };
 148 
 149 typedef struct {
 150         char *signature ;
 151         unsigned offset;
 152         unsigned length;
 153         unsigned char type;
 154 } Signature;
 155         
 156 static const Signature signatures[] = {
 157 #ifdef CONFIG_SCSI_SEAGATE
 158 {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
 159 {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 160 
 161 
 162 
 163 
 164 
 165 
 166 
 167 
 168 {"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
 169 {"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
 170 
 171 
 172 
 173 
 174 
 175 
 176 {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
 177 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
 178 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
 179 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
 180 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
 181 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FD},
 182 {"FUTURE DOMAIN TMC-950",                        5, 21, FD},
 183 #endif 
 184 }
 185 ;
 186 
 187 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
 188 #endif 
 189 
 190 
 191 
 192 
 193 
 194 static int hostno = -1;
 195 static void seagate_reconnect_intr(int);
 196 
 197 #ifdef FAST
 198 static int fast = 1;
 199 #endif 
 200 
 201 #ifdef SLOW_HANDSHAKE
 202 
 203 
 204 
 205 
 206 
 207 
 208 
 209 
 210 
 211 
 212 
 213 
 214 
 215 
 216 
 217 
 218 
 219 
 220 
 221 
 222 
 223 
 224 
 225 
 226 
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234 
 235 
 236 
 237 
 238 
 239 static int borken_calibration = 0;
 240 static void borken_init (void) {
     
 241   register int count = 0, start = jiffies + 1, stop = start + 25;
 242 
 243   while (jiffies < start);
 244   for (;jiffies < stop; ++count);
 245 
 246 
 247 
 248 
 249 
 250 
 251   borken_calibration =  (count * 4) / (SLOW_RATE*1024);
 252 
 253   if (borken_calibration < 1)
 254         borken_calibration = 1;
 255 #if (DEBUG & DEBUG_BORKEN)
 256   printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n", 
 257         hostno, BORKEN_RATE, borken_calibration);
 258 #endif
 259 }
 260 
 261 static inline void borken_wait(void) {
     
 262   register int count;
 263   for (count = borken_calibration; count && (STATUS & STAT_REQ); 
 264         --count);
 265   if (count)
 266 #if (DEBUG & DEBUG_BORKEN) 
 267         printk("scsi%d : borken timeout\n", hostno);
 268 #else
 269         ;
 270 #endif 
 271 }
 272 
 273 #endif 
 274 
 275 int seagate_st0x_detect (int hostnum)
     
 276         {
 277 #ifndef OVERRIDE
 278         int i,j;
 279 #endif 
 280 static struct sigaction seagate_sigaction = {
 281         &seagate_reconnect_intr,
 282         0,
 283         SA_INTERRUPT,
 284         NULL
 285 };
 286 
 287 
 288 
 289 
 290 #ifdef DEBUG 
 291         printk("Autodetecting seagate ST0x\n");
 292 #endif
 293         
 294         if (hostno != -1)
 295                 {
 296                 printk ("ERROR : seagate_st0x_detect() called twice.\n");
 297                 return 0;
 298                 }
 299 
 300       
 301 
 302 
 303         if (!controller_type) {
 304 #ifdef OVERRIDE
 305         base_address = (void *) OVERRIDE;
 306 
 307 
 308 #ifdef CONTROLLER
 309         controller_type = CONTROLLER;
 310 #else
 311 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
 312 #endif 
 313 #ifdef DEBUG
 314         printk("Base address overridden to %x, controller type is %s\n",
 315                 base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
 316 #endif 
 317 #else      
 318 
 319 
 320 
 321 
 322 
 323 
 324 
 325 
 326 
 327 
 328         for (i = 0; i < (sizeof (seagate_bases) / sizeof (char  * )); ++i)
 329                 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
 330                 if (!memcmp ((void *) (seagate_bases[i] +
 331                     signatures[j].offset), (void *) signatures[j].signature,
 332                     signatures[j].length)) {
 333                         base_address = (void *) seagate_bases[i];
 334                         controller_type = signatures[j].type;
 335                 }
 336 #endif 
 337         } 
 338  
 339         scsi_hosts[hostnum].this_id = (controller_type == SEAGATE) ? 7 : 6;
 340 
 341         if (base_address)
 342                 {
 343                 st0x_cr_sr =(void *) (((unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00)); 
 344                 st0x_dr = (void *) (((unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
 345 #ifdef DEBUG
 346                 printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
 347 #endif
 348 
 349 
 350 
 351 
 352                 hostno = hostnum;
 353                 if (irqaction((int) irq, &seagate_sigaction)) {
 354                         printk("scsi%d : unable to allocate IRQ%d\n",
 355                                 hostno, (int) irq);
 356                         return 0;
 357                 }
 358 #ifdef SLOW_HANDSHAKE
 359                 borken_init();
 360 #endif
 361                 
 362                 return 1;
 363                 }
 364         else
 365                 {
 366 #ifdef DEBUG
 367                 printk("ST0x not detected.\n");
 368 #endif
 369                 return 0;
 370                 }
 371         }
 372          
 373 const char *seagate_st0x_info(void) {
     
 374       static char buffer[256];
 375         sprintf(buffer, "scsi%d : %s at irq %d address %p options :"
 376 #ifdef ARBITRATE
 377 " ARBITRATE"
 378 #endif
 379 #ifdef SLOW_HANDSHAKE
 380 " SLOW_HANDSHAKE"
 381 #endif
 382 #ifdef FAST
 383 #ifdef FAST32
 384 " FAST32"
 385 #else
 386 " FAST"
 387 #endif
 388 #endif
 389  
 390 #ifdef LINKED
 391 " LINKED"
 392 #endif
 393               "\n", hostno, (controller_type == SEAGATE) ? "seagate" : 
 394               "FD TMC-8xx", irq, base_address);
 395         return buffer;
 396 }
 397 
 398 
 399 
 400 
 401 
 402 
 403 static unsigned char current_target, current_lun;
 404 static unsigned char *current_cmnd, *current_data;
 405 static int current_nobuffs;
 406 static struct scatterlist *current_buffer;
 407 static int current_bufflen;
 408 
 409 #ifdef LINKED
 410 
 411 
 412 
 413 
 414 
 415 
 416 
 417 static int linked_connected = 0;
 418 static unsigned char linked_target, linked_lun;
 419 #endif
 420 
 421 
 422 static void (*done_fn)(Scsi_Cmnd *) = NULL;
 423 static Scsi_Cmnd * SCint = NULL;
 424 
 425 
 426 
 427 
 428 
 429 
 430 #define NO_RECONNECT    0
 431 #define RECONNECT_NOW   1
 432 #define CAN_RECONNECT   2
 433 
 434 #ifdef LINKED
 435 
 436 
 437 
 438 
 439 
 440 
 441 
 442 #define LINKED_RIGHT    3
 443 #define LINKED_WRONG    4
 444 #endif
 445 
 446 
 447 
 448 
 449 
 450 static int should_reconnect = 0;
 451 
 452 
 453 
 454 
 455 
 456 
 457 
 458 static void seagate_reconnect_intr (int unused)
     
 459         {
 460         int temp;
 461         Scsi_Cmnd * SCtmp;
 462 
 463       
 464         sti();
 465 #if (DEBUG & PHASE_RESELECT)
 466         printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
 467 #endif
 468 
 469         if (!should_reconnect)
 470             printk("scsi%d: unexpected interrupt.\n", hostno);
 471         else {
 472                  should_reconnect = 0;
 473 
 474 #if (DEBUG & PHASE_RESELECT)
 475                 printk("scsi%d : internal_command("
 476                        "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno, 
 477                         current_target, current_data, current_bufflen);
 478 #endif
 479         
 480                 temp =  internal_command (current_target, current_lun,
 481                         current_cmnd, current_data, current_bufflen,
 482                         RECONNECT_NOW);
 483 
 484                 if (msg_byte(temp) != DISCONNECT) {
 485                         if (done_fn) {
 486 #if (DEBUG & PHASE_RESELECT)
 487                                 printk("scsi%d : done_fn(%d,%08x)", hostno, 
 488                                 hostno, temp);
 489 #endif
 490                                 if(!SCint) panic("SCint == NULL in seagate");
 491                                 SCtmp = SCint;
 492                                 SCint = NULL;
 493                                 SCtmp->result = temp;
 494                                 done_fn (SCtmp);
 495                         } else
 496                                 printk("done_fn() not defined.\n");
 497                         }
 498                 }
 499         } 
 500 
 501 
 502 
 503 
 504 
 505 
 506 
 507 
 508 
 509 
 510 
 511 
 512 static int recursion_depth = 0;
 513 
 514 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
     
 515         {
 516         int result, reconnect;
 517         Scsi_Cmnd * SCtmp;
 518 
 519         done_fn = done;
 520         current_target = SCpnt->target;
 521         current_lun = SCpnt->lun;
 522         (const void *) current_cmnd = SCpnt->cmnd;
 523         current_data = (unsigned char *) SCpnt->request_buffer;
 524         current_bufflen = SCpnt->request_bufflen;
 525         SCint = SCpnt;
 526         if(recursion_depth) {
 527           return 0;
 528         };
 529         recursion_depth++;
 530         do{
 531 #ifdef LINKED
 532 
 533 
 534 
 535 
 536           current_cmnd[COMMAND_SIZE(current_cmnd[0])] |= 0x01;
 537           if (linked_connected) {
 538 #if (DEBUG & DEBUG_LINKED) 
 539             printk("scsi%d : using linked commands, current I_T_L nexus is ",
 540               hostno);
 541 #endif
 542             if ((linked_target == current_target) && 
 543               (linked_lun == current_lun)) {
 544 #if (DEBUG & DEBUG_LINKED) 
 545             printk("correct\n");
 546 #endif
 547               reconnect = LINKED_RIGHT;
 548             } else {
 549 #if (DEBUG & DEBUG_LINKED) 
 550             printk("incorrect\n");
 551 #endif
 552               reconnect = LINKED_WRONG;
 553             }
 554           } else 
 555 #endif 
 556             reconnect = CAN_RECONNECT;
 557 
 558 
 559 
 560 
 561 
 562           result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
 563                                      SCint->request_bufflen, 
 564                                      reconnect);
 565           if (msg_byte(result) == DISCONNECT)  break;
 566           SCtmp = SCint;
 567           SCint = NULL;
 568           SCtmp->result = result;
 569           done_fn (SCtmp);
 570         } while(SCint);
 571         recursion_depth--;
 572         return 0;
 573       }
 574 
 575 int seagate_st0x_command (Scsi_Cmnd * SCpnt) {
     
 576         return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
 577                                  SCpnt->request_bufflen, 
 578                                  (int) NO_RECONNECT);
 579 }
 580         
 581 static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
     
 582                          void *buff, int bufflen, int reselect) {
 583         int len = 0;
 584         unsigned char *data = NULL;     
 585         struct scatterlist *buffer = NULL;
 586         int nobuffs = 0;
 587         int clock;                      
 588         int temp;
 589 #ifdef SLOW_HANDSHAKE
 590         int borken;     
 591 #endif
 592 
 593 
 594 #if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT) 
 595         int transfered = 0;
 596 #endif
 597 
 598 #if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
 599         (DEBUG & PHASE_EXIT))   
 600         int i;
 601 #endif
 602 
 603 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
 604         int phase=0, newphase;
 605 #endif
 606 
 607         int done = 0;
 608         unsigned char status = 0;       
 609         unsigned char message = 0;
 610         register unsigned char status_read;
 611 
 612         unsigned transfersize = 0, underflow = 0;
 613 
 614         incommand = 0;
 615         st0x_aborted = 0;
 616 
 617 #ifdef SLOW_HANDSHAKE
 618         borken = (int) scsi_devices[SCint->index].borken;
 619 #endif
 620 
 621 #if (DEBUG & PRINT_COMMAND)
 622         printk ("scsi%d : target = %d, command = ", hostno, target);
 623         print_command((unsigned char *) cmnd);
 624         printk("\n");
 625 #endif
 626 
 627 #if (DEBUG & PHASE_RESELECT)
 628         switch (reselect) {
 629         case RECONNECT_NOW :
 630                 printk("scsi%d : reconnecting\n", hostno);
 631                 break;
 632 #ifdef LINKED
 633         case LINKED_RIGHT : 
 634                 printk("scsi%d : connected, can reconnect\n", hostno);
 635                 break;
 636         case LINKED_WRONG :
 637                 printk("scsi%d : connected to wrong target, can reconnect\n",
 638                         hostno);
 639                 break;          
 640 #endif
 641         case CAN_RECONNECT :
 642                 printk("scsi%d : allowed to reconnect\n", hostno);
 643                 break;
 644         default :
 645                 printk("scsi%d : not allowed to reconnect\n", hostno);
 646         }
 647 #endif
 648         
 649 
 650         if (target == (controller_type == SEAGATE ? 7 : 6))
 651                 return DID_BAD_TARGET;
 652 
 653 
 654 
 655 
 656 
 657 
 658 
 659         switch (reselect) {
 660         case RECONNECT_NOW:
 661 #if (DEBUG & PHASE_RESELECT)
 662                 printk("scsi%d : phase RESELECT \n", hostno);
 663 #endif
 664 
 665 
 666 
 667 
 668 
 669 
 670 
 671 
 672 
 673                 
 674                 for (clock = jiffies + 10, temp = 0; (jiffies < clock) &&
 675                      !(STATUS & STAT_IO););
 676                 
 677                 if (jiffies >= clock)
 678                         {
 679 #if (DEBUG & PHASE_RESELECT)
 680                         printk("scsi%d : RESELECT timed out while waiting for IO .\n",
 681                                 hostno);
 682 #endif
 683                         return (DID_BAD_INTR << 16);
 684                         }
 685 
 686 
 687 
 688 
 689 
 690  
 691                 if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
 692                         {
 693 #if (DEBUG & PHASE_RESELECT)
 694                         printk("scsi%d : detected reconnect request to different target.\n" 
 695                                "\tData bus = %d\n", hostno, temp);
 696 #endif
 697                         return (DID_BAD_INTR << 16);
 698                         }
 699 
 700                 if (!(temp & (1 << current_target)))
 701                         {
 702                         printk("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
 703                                 hostno, temp);
 704                         return (DID_BAD_INTR << 16);
 705                         }
 706 
 707                 buffer=current_buffer;  
 708                 cmnd=current_cmnd;      
 709                 data=current_data;      
 710                 len=current_bufflen;    
 711                 nobuffs=current_nobuffs;
 712 
 713 
 714 
 715 
 716 
 717 
 718 #if 1
 719                 CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
 720 #else
 721                 CONTROL = (BASE_CMD | CMD_BSY);
 722 #endif
 723 
 724 
 725 
 726 
 727 
 728 
 729                 for (clock = jiffies + 10; (jiffies < clock) &&  (STATUS & STAT_SEL););
 730 
 731                 if (jiffies >= clock)
 732                         { 
 733                         CONTROL = (BASE_CMD | CMD_INTR);
 734 #if (DEBUG & PHASE_RESELECT)
 735                         printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
 736                                 hostno);
 737 #endif
 738                         return (DID_BAD_INTR << 16);                             
 739                         }
 740 
 741                 CONTROL = BASE_CMD;
 742 
 743 
 744 
 745 
 746       
 747                 break;
 748         case CAN_RECONNECT:
 749 
 750 #ifdef LINKED
 751 
 752 
 753 
 754 
 755 
 756 
 757   
 758 connect_loop :
 759 
 760 #endif
 761 
 762 #if (DEBUG & PHASE_BUS_FREE)
 763                 printk ("scsi%d : phase = BUS FREE \n", hostno);
 764 #endif
 765 
 766 
 767 
 768 
 769 
 770 
 771 
 772 
 773 
 774 
 775                 clock = jiffies + ST0X_BUS_FREE_DELAY;  
 776 
 777 #if !defined (ARBITRATE) 
 778                 while (((STATUS |  STATUS | STATUS) & 
 779                          (STAT_BSY | STAT_SEL)) && 
 780                          (!st0x_aborted) && (jiffies < clock));
 781 
 782                 if (jiffies > clock)
 783                         return retcode(DID_BUS_BUSY);
 784                 else if (st0x_aborted)
 785                         return retcode(st0x_aborted);
 786 #endif
 787 
 788 #if (DEBUG & PHASE_SELECTION)
 789                 printk("scsi%d : phase = SELECTION\n", hostno);
 790 #endif
 791 
 792                 clock = jiffies + ST0X_SELECTION_DELAY;
 793 
 794 
 795 
 796 
 797 
 798 
 799 
 800 
 801 
 802 
 803 
 804                 
 805 #if defined(ARBITRATE)  
 806         cli();
 807         CONTROL = 0;
 808         DATA = (controller_type == SEAGATE) ? 0x80 : 0x40;
 809         CONTROL = CMD_START_ARB; 
 810         sti();
 811         while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
 812                 (jiffies < clock) && !st0x_aborted);
 813 
 814         if (!(status_read & STAT_ARB_CMPL)) {
 815 #if (DEBUG & PHASE_SELECTION)
 816                 if (status_read & STAT_SEL) 
 817                         printk("scsi%d : arbitration lost\n", hostno);
 818                 else
 819                         printk("scsi%d : arbitration timeout.\n", hostno);
 820 #endif
 821                 CONTROL = BASE_CMD;
 822                 return retcode(DID_NO_CONNECT);
 823         };
 824 
 825 #if (DEBUG & PHASE_SELECTION)
 826         printk("scsi%d : arbitration complete\n", hostno);
 827 #endif
 828 #endif
 829 
 830 
 831 
 832 
 833 
 834 
 835 
 836 
 837 
 838 
 839 
 840 
 841 
 842 
 843         cli();
 844         DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
 845         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | 
 846                 (reselect ? CMD_ATTN : 0);
 847         sti();
 848                 while (!((status_read = STATUS) & STAT_BSY) && 
 849                         (jiffies < clock) && !st0x_aborted)
 850 
 851 #if 0 && (DEBUG & PHASE_SELECTION)
 852                 {
 853                 temp = clock - jiffies;
 854 
 855                 if (!(jiffies % 5))
 856                         printk("seagate_st0x_timeout : %d            \r",temp);
 857         
 858                 }
 859                 printk("Done.                                             \n");
 860                 printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", 
 861                         hostno, status_read, temp, st0x_aborted);
 862 #else
 863                 ;
 864 #endif
 865         
 866 
 867                 if ((jiffies >= clock)  && !(status_read & STAT_BSY))
 868                         {
 869 #if (DEBUG & PHASE_SELECTION)
 870                         printk ("scsi%d : NO CONNECT with target %d, status = %x \n", 
 871                                 hostno, target, STATUS);
 872 #endif
 873                         return retcode(DID_NO_CONNECT);
 874                         }
 875 
 876 
 877 
 878 
 879 
 880 
 881 
 882                 if (st0x_aborted) {
 883                         CONTROL = BASE_CMD;
 884                         if (STATUS & STAT_BSY) {
 885                                 printk("scsi%d : BST asserted after we've been aborted.\n",
 886                                         hostno);
 887                                 seagate_st0x_reset(NULL);
 888                                 return retcode(DID_RESET);
 889                         }
 890                         return retcode(st0x_aborted);
 891                 }       
 892 
 893 
 894 
 895         if ((nobuffs = SCint->use_sg)) {
 896 #if (DEBUG & DEBUG_SG)
 897         {
 898         int i;
 899         printk("scsi%d : scatter gather requested, using %d buffers.\n",
 900                 hostno, nobuffs);
 901         for (i = 0; i < nobuffs; ++i)
 902                 printk("scsi%d : buffer %d address = %08x length = %d\n",
 903                         hostno, i, buffer[i].address, buffer[i].length);
 904         }
 905 #endif
 906                 
 907                 buffer = (struct scatterlist *) SCint->buffer;
 908                 len = buffer->length;
 909                 data = (unsigned char *) buffer->address;
 910         } else {
 911 #if (DEBUG & DEBUG_SG)
 912         printk("scsi%d : scatter gather not requested.\n", hostno);
 913 #endif
 914                 buffer = NULL;
 915                 len = SCint->request_bufflen;
 916                 data = (unsigned char *) SCint->request_buffer;
 917         }
 918 
 919 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
 920         printk("scsi%d : len = %d\n", hostno, len);
 921 #endif
 922 
 923                 break;
 924 #ifdef LINKED
 925         case LINKED_RIGHT:
 926                 break;
 927         case LINKED_WRONG:
 928                 break;
 929 #endif
 930         }
 931 
 932 
 933 
 934 
 935 
 936 
 937 
 938 
 939 
 940 
 941         
 942         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | 
 943                 (((reselect == CAN_RECONNECT)
 944 #ifdef LINKED 
 945                 || (reselect == LINKED_WRONG)
 946 #endif 
 947                 )  ? CMD_ATTN : 0) ;
 948         
 949 
 950 
 951 
 952 
 953 
 954 
 955 
 956 
 957 
 958 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
 959         printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 960 #endif  
 961 
 962         incommand = 1;
 963         transfersize = SCint->transfersize;
 964         underflow = SCint->underflow;
 965 
 966 
 967 
 968 
 969 
 970 
 971 
 972 
 973 
 974 
 975         while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 
 976                 {
 977 #ifdef PARITY
 978                 if (status_read & STAT_PARITY)
 979                         {
 980                         printk("scsi%d : got parity error\n", hostno);
 981                         st0x_aborted = DID_PARITY;
 982                         }       
 983 #endif
 984 
 985                 if (status_read & STAT_REQ)
 986                         {
 987 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
 988                         if ((newphase = (status_read & REQ_MASK)) != phase)
 989                                 {
 990                                 phase = newphase;
 991                                 switch (phase)
 992                                 {
 993                                 case REQ_DATAOUT: 
 994                                         printk("scsi%d : phase = DATA OUT\n",
 995                                                 hostno); 
 996                                         break;
 997                                 case REQ_DATAIN : 
 998                                         printk("scsi%d : phase = DATA IN\n",
 999                                                 hostno); 
1000                                         break;
1001                                 case REQ_CMDOUT : 
1002                                         printk("scsi%d : phase = COMMAND OUT\n",
1003                                                 hostno); 
1004                                         break;
1005                                 case REQ_STATIN :
1006                                          printk("scsi%d : phase = STATUS IN\n",
1007                                                 hostno); 
1008                                         break;
1009                                 case REQ_MSGOUT :
1010                                         printk("scsi%d : phase = MESSAGE OUT\n",
1011                                                 hostno); 
1012                                         break;
1013                                 case REQ_MSGIN :
1014                                         printk("scsi%d : phase = MESSAGE IN\n",
1015                                                 hostno);
1016                                         break;
1017                                 default : 
1018                                         printk("scsi%d : phase = UNKNOWN\n",
1019                                                 hostno); 
1020                                         st0x_aborted = DID_ERROR; 
1021                                 }       
1022                                 }
1023 #endif
1024                 switch (status_read & REQ_MASK)
1025                 {                       
1026                 case REQ_DATAOUT : 
1027 
1028 
1029 
1030 
1031 
1032 #ifdef FAST 
1033 if (!len) {
1034 #if 0 
1035         printk("scsi%d: underflow to target %d lun %d \n", 
1036                 hostno, target, lun);
1037         st0x_aborted = DID_ERROR;
1038         fast = 0;
1039 #endif
1040         break;
1041 }
1042 
1043 if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
1044 #ifdef FAST32
1045         && !(transfersize % 4)
1046 #endif
1047         ) {
1048 #if (DEBUG & DEBUG_FAST) 
1049         printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
1050                "         len = %d, data = %08x\n", hostno, SCint->underflow, 
1051                SCint->transfersize, len, data);
1052 #endif
1053 
1054         __asm__("
1055         cld;
1056 "
1057 #ifdef FAST32
1058 "       shr $2, %%ecx;
1059 1:      lodsl;
1060         movl %%eax, (%%edi);
1061 "
1062 #else
1063 "1:     lodsb;
1064         movb %%al, (%%edi);
1065 "
1066 #endif
1067 "       loop 1b;" : :
1068         
1069         "D" (st0x_dr), "S" (data), "c" (SCint->transfersize) :
1070         
1071         "eax", "ecx", "esi" );
1072 
1073         len -= transfersize;
1074         data += transfersize;
1075 
1076 #if (DEBUG & DEBUG_FAST)
1077         printk("scsi%d : FAST transfer complete len = %d data = %08x\n", 
1078                 hostno, len, data);
1079 #endif
1080 
1081 
1082 } else 
1083 #endif
1084 
1085 {
1086 
1087 
1088 
1089 
1090                 __asm__ (
1091 
1092 
1093 
1094 
1095 
1096 
1097 
1098 
1099 
1100 
1101         "\torl %%ecx, %%ecx
1102         jz 2f
1103 
1104         cld
1105 
1106         movl _st0x_cr_sr, %%ebx
1107         movl _st0x_dr, %%edi
1108         
1109 1:      movb (%%ebx), %%al\n"
1110 
1111 
1112 
1113 
1114         "\ttest $1, %%al
1115         jz 2f\n"
1116 
1117 
1118 
1119 
1120         "\ttest $0xe, %%al
1121         jnz 2f  \n"
1122 
1123 
1124       
1125         "\ttest $0x10, %%al
1126         jz 1b
1127         lodsb
1128         movb %%al, (%%edi) 
1129         loop 1b
1130 
1131 2: 
1132                                                                         ":
1133 
1134 "=S" (data), "=c" (len) :
1135 
1136 "0" (data), "1" (len) :
1137 
1138 "eax", "ebx", "edi"); 
1139 }
1140 
1141                         if (!len && nobuffs) {
1142                                 --nobuffs;
1143                                 ++buffer;
1144                                 len = buffer->length;
1145                                 data = (unsigned char *) buffer->address;
1146 #if (DEBUG & DEBUG_SG)
1147         printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
1148                 hostno, len, data);
1149 #endif
1150                         }
1151                         break;
1152 
1153                 case REQ_DATAIN : 
1154 #ifdef SLOW_HANDSHAKE
1155         if (borken) {
1156 #if (DEBUG & (PHASE_DATAIN))
1157                 transfered += len;
1158 #endif
1159                 for (; len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
1160                         STAT_REQ); --len) {
1161                                 *data++ = DATA;
1162                                 borken_wait();
1163 }
1164 #if (DEBUG & (PHASE_DATAIN))
1165                 transfered -= len;
1166 #endif
1167         } else
1168 #endif
1169 #ifdef FAST
1170 if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
1171 #ifdef FAST32
1172         && !(transfersize % 4)
1173 #endif
1174         ) {
1175 #if (DEBUG & DEBUG_FAST) 
1176         printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
1177                "         len = %d, data = %08x\n", hostno, SCint->underflow, 
1178                SCint->transfersize, len, data);
1179 #endif
1180         __asm__("
1181         cld;
1182 "
1183 #ifdef FAST32
1184 "       shr $2, %%ecx;
1185 1:      movl (%%esi), %%eax;
1186         stosl;
1187 "
1188 #else
1189 "1:     movb (%%esi), %%al;
1190         stosb;
1191 "
1192 #endif
1193 
1194 "       loop 1b;" : :
1195         
1196         "S" (st0x_dr), "D" (data), "c" (SCint->transfersize) :
1197         
1198         "eax", "ecx", "edi");
1199 
1200         len -= transfersize;
1201         data += transfersize;
1202 
1203 #if (DEBUG & PHASE_DATAIN)
1204         printk("scsi%d: transfered += %d\n", hostno, transfersize);
1205         transfered += transfersize;
1206 #endif
1207 
1208 #if (DEBUG & DEBUG_FAST)
1209         printk("scsi%d : FAST transfer complete len = %d data = %08x\n", 
1210                 hostno, len, data);
1211 #endif
1212 
1213 } else
1214 #endif
1215 {
1216 
1217 #if (DEBUG & PHASE_DATAIN)
1218         printk("scsi%d: transfered += %d\n", hostno, len);
1219         transfered += len;      
1220 
1221 #endif
1222         
1223 
1224 
1225 
1226 
1227  
1228                         __asm__ (
1229 
1230 
1231 
1232 
1233 
1234 
1235 
1236 
1237 
1238         "\torl %%ecx, %%ecx
1239         jz 2f
1240 
1241         cld
1242         movl _st0x_cr_sr, %%esi
1243         movl _st0x_dr, %%ebx
1244 
1245 1:      movb (%%esi), %%al\n"
1246 
1247 
1248 
1249 
1250         "\ttest $1, %%al 
1251         jz 2f\n"
1252 
1253 
1254 
1255 
1256         "\tmovb $0xe, %%ah      
1257         andb %%al, %%ah
1258         cmpb $0x04, %%ah
1259         jne 2f\n"
1260                 
1261 
1262 
1263       
1264         "\ttest $0x10, %%al
1265         jz 1b
1266 
1267         movb (%%ebx), %%al      
1268         stosb   
1269         loop 1b\n"
1270 
1271 "2:\n"
1272                                                                         :
1273 
1274 "=D" (data), "=c" (len) :
1275 
1276 "0" (data), "1" (len) :
1277 
1278 "eax","ebx", "esi"); 
1279 
1280 #if (DEBUG & PHASE_DATAIN)
1281         printk("scsi%d: transfered -= %d\n", hostno, len);
1282         transfered -= len;              
1283 
1284 #endif
1285 }
1286         
1287                         if (!len && nobuffs) {
1288                                 --nobuffs;
1289                                 ++buffer;
1290                                 len = buffer->length;
1291                                 data = (unsigned char *) buffer->address;
1292 #if (DEBUG & DEBUG_SG)
1293         printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
1294                 hostno, len, data);
1295 #endif
1296                         }
1297 
1298                         break;
1299 
1300                 case REQ_CMDOUT : 
1301                         while (((status_read = STATUS) & STAT_BSY) && 
1302                                ((status_read & REQ_MASK) == REQ_CMDOUT))
1303                                 if (status_read & STAT_REQ) {
1304                                         DATA = *(unsigned char *) cmnd;
1305                                         cmnd = 1+(unsigned char *) cmnd;
1306 #ifdef SLOW_HANDSHAKE
1307                                         if (borken) 
1308                                                 borken_wait();
1309 #endif
1310                                 }
1311                         break;
1312         
1313                 case REQ_STATIN : 
1314                         status = DATA;
1315                         break;
1316                                 
1317                 case REQ_MSGOUT : 
1318 
1319 
1320 
1321 
1322 
1323                         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
1324 
1325 
1326 
1327 
1328                         switch (reselect) {
1329                         case CAN_RECONNECT:
1330                                 DATA = IDENTIFY(1, lun);
1331 
1332 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT)) 
1333                                 printk("scsi%d : sent IDENTIFY message.\n", hostno);
1334 #endif
1335                                 break;
1336 #ifdef LINKED
1337                         case LINKED_WRONG:
1338                                 DATA = ABORT;
1339                                 linked_connected = 0;
1340                                 reselect = CAN_RECONNECT;
1341                                 goto connect_loop;
1342 #if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
1343                                 printk("scsi%d : sent ABORT message to cancle incorrect I_T_L nexus.\n", hostno);
1344 #endif
1345 #endif 
1346 #if (DEBUG & DEBUG_LINKED) 
1347             printk("correct\n");
1348 #endif
1349                         default:
1350                                 DATA = NOP;
1351                                 printk("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
1352                         }
1353                         break;
1354                                         
1355                 case REQ_MSGIN : 
1356                         switch (message = DATA) {
1357                         case DISCONNECT :
1358                                 should_reconnect = 1;
1359                                 current_data = data;    
1360                                 current_buffer = buffer;
1361                                 current_bufflen = len;  
1362                                 current_nobuffs = nobuffs;
1363 #ifdef LINKED
1364                                 linked_connected = 0;
1365 #endif
1366                                 done=1;
1367 #if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
1368                                 printk("scsi%d : disconnected.\n", hostno);
1369 #endif
1370                                 break;
1371 
1372 #ifdef LINKED
1373                         case LINKED_CMD_COMPLETE:
1374                         case LINKED_FLG_CMD_COMPLETE:
1375 #endif
1376                         case COMMAND_COMPLETE :
1377 
1378 
1379 
1380 #if (DEBUG & PHASE_MSGIN)       
1381                                 printk("scsi%d : command complete.\n", hostno);
1382 #endif
1383                                 done = 1;
1384                                 break;
1385                         case ABORT :
1386 #if (DEBUG & PHASE_MSGIN)
1387                                 printk("scsi%d : abort message.\n", hostno);
1388 #endif
1389                                 done=1;
1390                                 break;
1391                         case SAVE_POINTERS :
1392                                 current_buffer = buffer;
1393                                 current_bufflen = len;  
1394                                 current_data = data;    
1395                                 current_nobuffs = nobuffs;
1396 #if (DEBUG & PHASE_MSGIN)
1397                                 printk("scsi%d : pointers saved.\n", hostno);
1398 #endif 
1399                                 break;
1400                         case RESTORE_POINTERS:
1401                                 buffer=current_buffer;
1402                                 cmnd=current_cmnd;
1403                                 data=current_data;      
1404                                 len=current_bufflen;
1405                                 nobuffs=current_nobuffs;
1406 #if (DEBUG & PHASE_MSGIN)
1407                                 printk("scsi%d : pointers restored.\n", hostno);
1408 #endif
1409                                 break;
1410                         default:
1411 
1412 
1413 
1414 
1415 
1416 
1417 
1418 
1419 
1420 
1421                                 if (message & 0x80) {
1422 #if (DEBUG & PHASE_MSGIN)
1423                                         printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
1424                                                 hostno, target, message & 7);
1425 #endif
1426                                 } else {
1427 
1428 
1429 
1430 
1431 
1432 
1433 
1434 #if (DEBUG & PHASE_MSGIN)
1435                                         printk("scsi%d : unknown message %d from target %d.\n",
1436                                                 hostno,  message,   target);
1437 #endif  
1438                                 }
1439                         }
1440                         break;
1441 
1442                 default : 
1443                         printk("scsi%d : unknown phase.\n", hostno); 
1444                         st0x_aborted = DID_ERROR; 
1445                 }       
1446 
1447 #ifdef SLOW_HANDSHAKE
1448 
1449 
1450 
1451 
1452 
1453                 if (borken)
1454                         borken_wait();
1455 #endif
1456  
1457                 } 
1458                 } 
1459 
1460 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
1461         printk("scsi%d : Transfered %d bytes\n", hostno, transfered);
1462 #endif
1463 
1464 #if (DEBUG & PHASE_EXIT)
1465 #if 0           
1466         printk("Buffer : \n");
1467         for (i = 0; i < 20; ++i) 
1468                 printk ("%02x  ", ((unsigned char *) data)[i]); 
1469         printk("\n");
1470 #endif
1471         printk("scsi%d : status = ", hostno);
1472         print_status(status);
1473         printk("message = %02x\n", message);
1474 #endif
1475 
1476 
1477 
1478 #ifdef notyet
1479         if (st0x_aborted) {
1480                 if (STATUS & STAT_BSY) {        
1481                         seagate_st0x_reset(NULL);
1482                         st0x_aborted = DID_RESET;
1483                 } 
1484                 abort_confirm = 1;
1485         } 
1486 #endif
1487 
1488 #ifdef LINKED
1489 else {
1490 
1491 
1492 
1493 
1494 
1495 
1496 
1497 
1498 
1499 
1500                 switch (message) {
1501                 case LINKED_CMD_COMPLETE :
1502                 case LINKED_FLG_CMD_COMPLETE : 
1503                         message = COMMAND_COMPLETE;
1504                         linked_target = current_target;
1505                         linked_lun = current_lun;
1506                         linked_connected = 1;
1507 #if (DEBUG & DEBUG_LINKED)
1508                         printk("scsi%d : keeping I_T_L nexus established for linked command.\n", 
1509                                 hostno);
1510 #endif
1511 
1512 
1513 
1514                         if ((status == INTERMEDIATE_GOOD) ||
1515                                 (status == INTERMEDIATE_C_GOOD))
1516                                 status = GOOD;
1517                         
1518                         break;
1519 
1520 
1521 
1522 
1523 
1524 
1525                 default :
1526 #if (DEBUG & DEBUG_LINKED)
1527                         printk("scsi%d : closing I_T_L nexus.\n", hostno);
1528 #endif
1529                         linked_connected = 0;
1530                 }
1531         }
1532 #endif 
1533 
1534 
1535 
1536 
1537         if (should_reconnect) {
1538 #if (DEBUG & PHASE_RESELECT)
1539                 printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
1540                         hostno);
1541 #endif
1542                 CONTROL = BASE_CMD | CMD_INTR ;
1543         } else 
1544                 CONTROL = BASE_CMD;
1545 
1546         return retcode (st0x_aborted);
1547         }
1548 
1549 int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
     
1550         {
1551           st0x_aborted = DID_ABORT;
1552           
1553           return SCSI_ABORT_PENDING;
1554         }
1555 
1556 
1557 
1558 
1559         
1560 int seagate_st0x_reset (Scsi_Cmnd * SCpnt)
     
1561         {
1562         unsigned clock;
1563         
1564 
1565 
1566 
1567 
1568 #ifdef DEBUG
1569         printk("In seagate_st0x_reset()\n");
1570 #endif
1571 
1572 
1573         
1574                 
1575         CONTROL = BASE_CMD  | CMD_RST;
1576         clock=jiffies+2;
1577 
1578         
1579         
1580         
1581         while (jiffies < clock);
1582 
1583         CONTROL = BASE_CMD;
1584         
1585         st0x_aborted = DID_RESET;
1586 
1587 #ifdef DEBUG
1588         printk("SCSI bus reset.\n");
1589 #endif
1590         return SCSI_RESET_PENDING;
1591         }
1592 
1593 #ifdef CONFIG_BLK_DEV_SD
1594 
1595 #include <asm/segment.h>
1596 #include "sd.h"
1597 #include "scsi_ioctl.h"
1598 
1599 int seagate_st0x_biosparam(int size, int dev, int* ip) {
     
1600   unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page;
1601   int *sizes, result, formatted_sectors, total_sectors;
1602   int cylinders, heads, sectors;
1603 
1604   Scsi_Device *disk;
1605 
1606   disk = rscsi_disks[MINOR(dev) >> 4].device;
1607 
1608 
1609 
1610 
1611 
1612 
1613   if (disk->scsi_level < 2) 
1614         return -1;
1615 
1616   sizes = (int *) buf;
1617   data = (unsigned char *) (sizes + 2);
1618 
1619   cmd[0] = MODE_SENSE;
1620   cmd[1] = (disk->lun << 5) & 0xe5;
1621   cmd[2] = 0x04; 
1622   cmd[3] = 0;
1623   cmd[4] = 255;
1624   cmd[5] = 0;
1625 
1626 
1627 
1628 
1629 
1630 
1631   sizes[0] = 0;
1632   sizes[1] = 256;
1633 
1634   memcpy (data, cmd, 6);
1635 
1636   if (!(result = kernel_scsi_ioctl (disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
1637 
1638 
1639 
1640 
1641 
1642     page = data + 4 + data[3];
1643     heads = (int) page[5];
1644     cylinders = (page[2] << 16) | (page[3] << 8) | page[4];
1645 
1646     cmd[2] = 0x03; 
1647     memcpy (data, cmd, 6);
1648 
1649     if (!(result = kernel_scsi_ioctl (disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
1650       page = data + 4 + data[3];
1651       sectors = (page[10] << 8) | page[11];     
1652 
1653         
1654 
1655 
1656 
1657 
1658 
1659       formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8) |
1660         data[4 + 3] ;
1661 
1662       total_sectors = (heads * cylinders * sectors);
1663 
1664 
1665 
1666 
1667 
1668 
1669 
1670 
1671      
1672 printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n",
1673     hostno, heads, cylinders, sectors, total_sectors, formatted_sectors);
1674 
1675       if (!heads || !sectors || !cylinders)
1676         result = -1;
1677       else
1678         cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors));
1679 
1680 
1681 
1682 
1683 
1684 
1685 
1686       if ((cylinders > 1024) || (sectors > 64)) 
1687         result = -1;
1688       else {
1689         ip[0] = heads;
1690         ip[1] = sectors;
1691         ip[2] = cylinders;
1692       }
1693 
1694 
1695 
1696 
1697 
1698 
1699       }
1700     }
1701     
1702   return result;
1703 }
1704 #endif 
1705 
1706 #endif  
1707