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_st0x_command
  4. seagate_st0x_abort
  5. seagate_st0x_reset

   1 /*
   2  *      seagate.c Copyright (C) 1992 Drew Eckhardt 
   3  *      low level scsi driver for ST01/ST02 by
   4  *              Drew Eckhardt 
   5  *
   6  *      <drew@colorado.edu>
   7  */
   8 
   9 #include <linux/config.h>
  10 
  11 #ifdef CONFIG_SCSI_SEAGATE
  12 #include <linux/sched.h>
  13 
  14 #include "seagate.h"
  15 #include "scsi.h"
  16 #include "hosts.h"
  17 
  18 static int incommand;                   /*
  19                                                 set if arbitration has finished and we are 
  20                                                 in some command phase.
  21                                         */
  22 
  23 static void *base_address = NULL;       /*
  24                                                 Where the card ROM starts,
  25                                                 used to calculate memory mapped
  26                                                 register location.
  27                                         */
  28 static volatile int abort_confirm = 0;
  29 
  30 volatile void *st0x_cr_sr;       /*
  31                                                 control register write,
  32                                                 status register read.
  33                                                 256 bytes in length.
  34 
  35                                                 Read is status of SCSI BUS,
  36                                                 as per STAT masks.
  37 
  38                                         */
  39 
  40 
  41 static volatile void *st0x_dr;         /*
  42                                                 data register, read write
  43                                                 256 bytes in length.
  44                                         */
  45 
  46 
  47 static volatile int st0x_aborted=0;     /* 
  48                                                 set when we are aborted, ie by a time out, etc.
  49                                         */
  50 
  51                                         /*
  52                                                 In theory, we have a nice auto
  53                                                 detect routine - but this 
  54                                                 overides it. 
  55                                         */
  56 
  57                         
  58 #define retcode(result) (((result) << 16) | (message << 8) | status)                    
  59 #define STATUS (*(unsigned char *) st0x_cr_sr)
  60 #define CONTROL STATUS 
  61 #define DATA (*(unsigned char *) st0x_dr)
  62 
  63 #ifndef OVERRIDE                
  64 static const char *  seagate_bases[] = {(char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, (char *) 0xce000, (char *) 0xce000,
  65                                         (char *) 0xdc000, (char *) 0xde000};
  66 typedef struct 
  67         {
  68         char *signature ;
  69         unsigned offset;
  70         unsigned length;
  71         } Signature;
  72         
  73 static const Signature signatures[] = {
  74 {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40},
  75 {"SEAGATE SCSI BIOS ",16, 17},
  76 {"SEAGATE SCSI BIOS ",17, 17}};
  77 /*
  78         Note that the last signature handles BIOS revisions 3.0.0 and 
  79         3.2 - the real ID's are 
  80 
  81 SEAGATE SCSI BIOS REVISION 3.0.0
  82 SEAGATE SCSI BIOS REVISION 3.2
  83 
  84 */
  85 
  86 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
  87 #endif
  88 
  89 int seagate_st0x_detect (int hostnum)
     /* [previous][next][first][last][top][bottom][index][help] */
  90         {
  91         #ifndef OVERRIDE
  92                 int i,j;
  93         #endif
  94 
  95         /*
  96                 First, we try for the manual override.
  97         */
  98         #ifdef DEBUG 
  99                 printk("Autodetecting seagate ST0x\n");
 100         #endif
 101         
 102         base_address = NULL;
 103         #ifdef OVERRIDE
 104                 base_address = (void *) OVERRIDE;       
 105                 #ifdef DEBUG
 106                         printk("Base address overridden to %x\n", base_address);
 107                 #endif
 108         #else   
 109         /*
 110                 To detect this card, we simply look for the SEAGATE SCSI
 111                 from the BIOS version notice in all the possible locations
 112                 of the ROM's.
 113         */
 114 
 115         for (i = 0; i < (sizeof (seagate_bases) / sizeof (char  * )); ++i)
 116                 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
 117                 if (!memcmp ((void *) (seagate_bases[i] +
 118                     signatures[j].offset), (void *) signatures[j].signature,
 119                     signatures[j].length))
 120                         base_address = (void *) seagate_bases[i];
 121         #endif
 122  
 123         if (base_address)
 124                 {
 125                 st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00); 
 126                 st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00);
 127                 #ifdef DEBUG
 128                         printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
 129                 #endif
 130                 return -1;
 131                 }
 132         else
 133                 {
 134                 #ifdef DEBUG
 135                         printk("ST0x not detected.\n");
 136                 #endif
 137                 return 0;
 138                 }
 139         }
 140          
 141         
 142 
 143 char *seagate_st0x_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145         static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n"
 146 "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/04/24 18:01:50 root Exp root $\n";
 147         return buffer;
 148 }
 149 
 150 
 151 
 152 int seagate_st0x_command(unsigned char target, const void *cmnd,
     /* [previous][next][first][last][top][bottom][index][help] */
 153                          void *buff, int bufflen)
 154         {
 155         int len;                        
 156         unsigned char *data;    
 157 
 158         int clock;                      /*
 159                                                 We use clock for timeouts, etc.   This replaces the 
 160                                                 seagate_st0x_timeout that we had been using.
 161                                         */
 162         #if (DEBUG & PHASE_SELECTION)
 163                 int temp;
 164         #endif
 165 
 166         #if (DEBUG & PHASE_EXIT)
 167                  void *retaddr, *realretaddr;
 168         #endif
 169 
 170         #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))    
 171                 int i;
 172         #endif
 173 
 174         #if (DEBUG & PHASE_ETC)
 175                 int phase=0, newphase;
 176         #endif
 177 
 178         int done = 0;
 179         unsigned char status = 0;       
 180         unsigned char message = 0;
 181         register unsigned char status_read;
 182 
 183         #if (DEBUG & PHASE_EXIT)
 184                  __asm__("
 185 movl 4(%%ebp), %%eax 
 186 ":"=a" (realretaddr):);
 187                 printk("return address = %08x\n", realretaddr);
 188         #endif
 189 
 190 
 191         len=bufflen;
 192         data=(unsigned char *) buff;
 193 
 194         incommand = 0;
 195         st0x_aborted = 0;
 196 
 197         #if (DEBUG & PRINT_COMMAND)
 198                 printk ("seagate_st0x_command, target = %d, command = ", target);
 199                 for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
 200                         printk("%02x ",  ((unsigned char *) cmnd)[i]);
 201                 printk("\n");
 202         #endif
 203         
 204         if (target > 6)
 205                 return DID_BAD_TARGET;
 206 
 207         
 208         #if (DEBUG & PHASE_BUS_FREE)
 209                 printk ("SCSI PHASE = BUS FREE \n");
 210         #endif
 211 
 212         /*
 213 
 214                 BUS FREE PHASE
 215 
 216                 On entry, we make sure that the BUS is in a BUS FREE
 217                 phase, by insuring that both BSY and SEL are low for
 218                 at least one bus settle delay.  The standard requires a
 219                 minimum of 400 ns, which is 16 clock cycles on a
 220                 386-40  .
 221 
 222                 This doesn't give us much time - so we'll do two several
 223                 reads to be sure be sure.
 224         */
 225 
 226         clock = jiffies + ST0X_BUS_FREE_DELAY;  
 227 
 228         while (((STATUS |  STATUS | STATUS) & 
 229                  (STAT_BSY | STAT_SEL)) && 
 230                  (!st0x_aborted) && (jiffies < clock));
 231 
 232         if (jiffies > clock)
 233                 return retcode(DID_BUS_BUSY);
 234         else if (st0x_aborted)
 235                 return retcode(st0x_aborted);
 236 
 237         /*
 238                 Bus free has been detected, within BUS settle.  I used to support an arbitration
 239                 phase - however, on the seagate, this degraded performance by a factor > 10 - so
 240                 it is no more.
 241         */
 242 
 243         /*
 244                 SELECTION PHASE
 245 
 246                 Now, we select the disk, giving it the SCSI ID at data
 247                 and a command of PARITY if necessary, plus driver enable,
 248                 plus raise select signal.
 249         */
 250 
 251         #if (DEBUG & PHASE_SELECTION)
 252                 printk("SCSI PHASE = SELECTION\n");
 253         #endif
 254 
 255         clock = jiffies + ST0X_SELECTION_DELAY;
 256         DATA = (unsigned char) (1 << target);
 257 
 258         CONTROL =  BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL;
 259 
 260         /*
 261                 When the SCSI device decides that we're gawking at it, it will respond by asserting BUSY on the bus.
 262         */
 263         while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock) && !st0x_aborted)
 264 
 265 #if (DEBUG & PHASE_SELECTION)
 266                 {
 267                 temp = clock - jiffies;
 268 
 269                 if (!(jiffies % 5))
 270                         printk("seagate_st0x_timeout : %d            \r",temp);
 271         
 272                 }
 273                 printk("Done.                                             \n\r");
 274                 printk("Status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", status_read, temp,
 275                         st0x_aborted);
 276 #else
 277                 ;
 278 #endif
 279         
 280 
 281         if ((jiffies > clock)  || (!st0x_aborted & !(status_read & STAT_BSY)))
 282                 {
 283                 #if (DEBUG & PHASE_SELECT)
 284                         printk ("NO CONNECT with target %d, status = %x \n", target, STATUS);
 285                 #endif
 286                 return retcode(DID_NO_CONNECT);
 287                 }
 288 
 289         /*
 290                 If we have been aborted, and we have a command in progress, IE the target still has
 291                 BSY asserted, then we will reset the bus, and notify the midlevel driver to
 292                 expect sense.
 293         */
 294 
 295         if (st0x_aborted)
 296                 {
 297                 CONTROL = BASE_CMD;
 298                 if (STATUS & STAT_BSY)
 299                         {
 300                         seagate_st0x_reset();
 301                         return retcode(DID_RESET);
 302                         }
 303                 
 304                 return retcode(st0x_aborted);
 305                 }       
 306         
 307         /*
 308                 COMMAND PHASE
 309                 The device has responded with a BSY, so we may now enter
 310                 the information transfer phase, where we will send / recieve
 311                 data and command as directed by the target.
 312 
 313 
 314                 The nasty looking read / write inline assembler loops we use for 
 315                 DATAIN and DATAOUT phases are approximately 4-5 times as fast as 
 316                 the 'C' versions - since we're moving 1024 bytes of data, this
 317                 really adds up.
 318         */
 319 
 320         #if (DEBUG & PHASE_ETC)
 321                 printk("PHASE = information transfer\n");
 322         #endif  
 323 
 324         incommand = 1;
 325 
 326         /*
 327                 Enable command
 328         */
 329 
 330         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
 331 
 332         /*
 333                 Now, we poll the device for status information,
 334                 and handle any requests it makes.  Note that since we are unsure of 
 335                 how much data will be flowing across the system, etc and cannot 
 336                 make reasonable timeouts, that we will instead have the midlevel
 337                 driver handle any timeouts that occur in this phase.
 338         */
 339 
 340         while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) 
 341                         {
 342                         #ifdef PARITY
 343                                 if (status_read & STAT_PARITY)
 344                                         {
 345                                         done = 1;
 346                                         st0x_aborted = DID_PARITY;
 347                                         }       
 348                         #endif
 349 
 350                         if (status_read & STAT_REQ)
 351                                 {
 352                                 #if (DEBUG & PHASE_ETC)
 353                                         if ((newphase = (status_read & REQ_MASK)) != phase)
 354                                                 {
 355                                                 phase = newphase;
 356                                                 switch (phase)
 357                                                         {
 358                                                         case REQ_DATAOUT : printk("SCSI PHASE = DATA OUT\n"); break;
 359                                                         case REQ_DATAIN : printk("SCSI PHASE = DATA IN\n"); break;
 360                                                         case REQ_CMDOUT : printk("SCSI PHASE = COMMAND OUT\n"); break;
 361                                                         case REQ_STATIN : printk("SCSI PHASE = STATUS IN\n"); break;
 362                                                         case REQ_MSGOUT : printk("SCSI PHASE = MESSAGE OUT\n"); break;
 363                                                         case REQ_MSGIN : printk("SCSI PHASE = MESSAGE IN\n"); break;
 364                                                         default : printk("UNKNOWN PHASE"); st0x_aborted = 1; done = 1;
 365                                                         }       
 366                                                 }
 367                                 #endif
 368 
 369                                 switch (status_read & REQ_MASK)
 370                                         {                       
 371                                         case REQ_DATAOUT : 
 372 
 373         /*
 374                 We loop as long as we are in a data out phase, there is data to send, and BSY is still
 375                 active
 376         */
 377                                                         __asm__ ("
 378 
 379 /*
 380         Local variables : 
 381         len = ecx
 382         data = esi
 383         st0x_cr_sr = ebx
 384         st0x_dr =  edi
 385 
 386         Test for any data here at all.
 387 */
 388         movl %0, %%esi          /* local value of data */
 389         movl %1, %%ecx          /* local value of len */        
 390         orl %%ecx, %%ecx
 391         jz 2f
 392 
 393         cld
 394 
 395         movl _st0x_cr_sr, %%ebx
 396         movl _st0x_dr, %%edi
 397         
 398 1:      movb (%%ebx), %%al
 399 /*
 400         Test for BSY
 401 */
 402 
 403         test $1, %%al 
 404         jz 2f
 405 
 406 /*
 407         Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
 408 */
 409         test $0xe, %%al
 410         jnz 2f  
 411 /*
 412         Test for REQ
 413 */      
 414         test $0x10, %%al
 415         jz 1b
 416         lodsb
 417         movb %%al, (%%edi) 
 418         loop 1b
 419 
 420 2: 
 421         movl %%esi, %2
 422         movl %%ecx, %3
 423                                                                         ":
 424 /* output */
 425 "=r" (data), "=r" (len) :
 426 /* input */
 427 "0" (data), "1" (len) :
 428 /* clobbered */
 429 "ebx", "ecx", "edi", "esi"); 
 430 
 431                                                         break;
 432 
 433                                         case REQ_DATAIN : 
 434         /*
 435                 We loop as long as we are in a data out phase, there is room to read, and BSY is still
 436                 active
 437         */
 438  
 439                                                         __asm__ ("
 440 /*
 441         Local variables : 
 442         ecx = len
 443         edi = data
 444         esi = st0x_cr_sr
 445         ebx = st0x_dr
 446 
 447         Test for room to read
 448 */
 449 
 450         movl %0, %%edi          /* data */
 451         movl %1, %%ecx          /* len */
 452         orl %%ecx, %%ecx
 453         jz 2f
 454 
 455         cld
 456         movl _st0x_cr_sr, %%esi
 457         movl _st0x_dr, %%ebx
 458 
 459 1:      movb (%%esi), %%al
 460 /*
 461         Test for BSY
 462 */
 463 
 464         test $1, %%al 
 465         jz 2f
 466 
 467 /*
 468         Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
 469 */
 470         movb $0xe, %%ah 
 471         andb %%al, %%ah
 472         cmpb $0x04, %%ah
 473         jne 2f
 474                 
 475 /*
 476         Test for REQ
 477 */      
 478         test $0x10, %%al
 479         jz 1b
 480 
 481         movb (%%ebx), %%al      
 482         stosb   
 483         loop 1b
 484 
 485 2:      movl %%edi, %2          /* data */
 486         movl %%ecx, %3          /* len */
 487                                                                         ":
 488 /* output */
 489 "=r" (data), "=r" (len) :
 490 /* input */
 491 "0" (data), "1" (len) :
 492 /* clobbered */
 493 "ebx", "ecx", "edi", "esi"); 
 494                                                         break;
 495 
 496                                         case REQ_CMDOUT : 
 497                                                         while (((status_read = STATUS) & STAT_BSY) && ((status_read & REQ_MASK) ==
 498                                                                 REQ_CMDOUT))
 499                                                                 DATA = *(unsigned char *) cmnd ++;
 500                                                 break;
 501         
 502                                         case REQ_STATIN : 
 503                                                 status = DATA;
 504                                                 break;
 505                                 
 506                                         case REQ_MSGOUT : 
 507                                                 DATA = MESSAGE_REJECT;
 508                                                 break;
 509                                         
 510                                         case REQ_MSGIN : 
 511                                                 if ((message = DATA) == COMMAND_COMPLETE)
 512                                                         done=1;
 513                                                 
 514                                                 break;
 515 
 516                                         default : printk("UNKNOWN PHASE"); st0x_aborted = DID_ERROR; 
 517                                         }       
 518                                 }
 519 
 520                 }
 521 
 522 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
 523         printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);
 524 #endif
 525 
 526 #if (DEBUG & PHASE_EXIT)
 527                 printk("Buffer : \n");
 528                 for (i = 0; i < 20; ++i) 
 529                         printk ("%02x  ", ((unsigned char *) buff)[i]);
 530                 printk("\n");
 531                 printk("Status = %02x, message = %02x\n", status, message);
 532 #endif
 533 
 534         
 535                 if (st0x_aborted)
 536                         {
 537                         if (STATUS & STAT_BSY)
 538                                 {
 539                                 seagate_st0x_reset();
 540                                 st0x_aborted = DID_RESET;
 541                                 }
 542                         abort_confirm = 1;
 543                         }       
 544                         
 545                 CONTROL = BASE_CMD;
 546 
 547 #if (DEBUG & PHASE_EXIT)
 548         __asm__("
 549 mov 4(%%ebp), %%eax
 550 ":"=a" (retaddr):);
 551 
 552         printk("Exiting seagate_st0x_command() - return address is %08x \n", retaddr);
 553         if (retaddr != realretaddr)
 554                 panic ("Corrupted stack : return address on entry != return address on exit.\n");
 555         
 556 #endif
 557 
 558                 return retcode (st0x_aborted);
 559         }
 560 
 561 int seagate_st0x_abort (int code)
     /* [previous][next][first][last][top][bottom][index][help] */
 562         {
 563         if (code)
 564                 st0x_aborted = code;
 565         else
 566                 st0x_aborted = DID_ABORT;
 567 
 568                 return 0;
 569         }
 570 
 571 /*
 572         the seagate_st0x_reset function resets the SCSI bus
 573 */
 574         
 575 int seagate_st0x_reset (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 576         {
 577         unsigned clock;
 578         /*
 579                 No timeouts - this command is going to fail because 
 580                 it was reset.
 581         */
 582 
 583 #ifdef DEBUG
 584         printk("In seagate_st0x_reset()\n");
 585 #endif
 586 
 587 
 588         /* assert  RESET signal on SCSI bus.  */
 589                 
 590         CONTROL = BASE_CMD  | CMD_RST;
 591         clock=jiffies+2;
 592 
 593         
 594         /* Wait.  */
 595         
 596         while (jiffies < clock);
 597 
 598         CONTROL = BASE_CMD;
 599         
 600         st0x_aborted = DID_RESET;
 601 
 602 #ifdef DEBUG
 603         printk("SCSI bus reset.\n");
 604 #endif
 605         return 0;
 606         }
 607 #endif  

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