root/drivers/scsi/NCR53c406a.c

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

DEFINITIONS

This source file includes following definitions.
  1. NCR53c406a_dma_setup
  2. NCR53c406a_dma_write
  3. NCR53c406a_dma_read
  4. NCR53c406a_dma_residual
  5. NCR53c406a_pio_read
  6. NCR53c406a_pio_write
  7. NCR53c406a_detect
  8. NCR53c406a_setup
  9. NCR53c406a_info
  10. internal_done
  11. wait_intr
  12. NCR53c406a_command
  13. NCR53c406a_queue
  14. NCR53c406a_abort
  15. NCR53c406a_reset
  16. NCR53c406a_biosparm
  17. NCR53c406a_intr
  18. irq_probe
  19. chip_init
  20. calc_port_addr

   1 /* 
   2  *  NCR53c406.c
   3  *  Low-level SCSI driver for NCR53c406a chip.
   4  *  Copyright (C) 1994, 1995 Normunds Saumanis (normunds@tech.swh.lv)
   5  * 
   6  *  LILO command line usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]
   7  *  Specify IRQ = 0 for non-interrupt driven mode.
   8  *  FASTPIO = 1 for fast pio mode, 0 for slow mode.
   9  *
  10  *  This program is free software; you can redistribute it and/or modify it
  11  *  under the terms of the GNU General Public License as published by the
  12  *  Free Software Foundation; either version 2, or (at your option) any
  13  *  later version.
  14  *
  15  *  This program is distributed in the hope that it will be useful, but
  16  *  WITHOUT ANY WARRANTY; without even the implied warranty of
  17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18  *  General Public License for more details.
  19  *
  20  */
  21 
  22 #define NCR53C406A_DEBUG 0
  23 #define VERBOSE_NCR53C406A_DEBUG 0
  24 
  25 /* Set this to 1 for PIO mode (recommended) or to 0 for DMA mode */
  26 #define USE_PIO 1
  27 
  28 #define USE_BIOS 0
  29 /* #define BIOS_ADDR 0xD8000 */ /* define this if autoprobe fails */
  30 /* #define PORT_BASE 0x330 */   /* define this if autoprobe fails */
  31 /* #define IRQ_LEV   0  */      /* define this if autoprobe fails */
  32 #define DMA_CHAN  5             /* this is ignored if DMA is disabled */
  33 
  34 /* Set this to 0 if you encounter kernel lockups while transferring 
  35  * data in PIO mode */
  36 #define USE_FAST_PIO 1
  37 
  38 /* ============= End of user configurable parameters ============= */
  39 
  40 #include <linux/module.h>
  41 
  42 #include <linux/errno.h>
  43 #include <linux/ioport.h>
  44 #include <linux/sched.h>
  45 #include <linux/interrupt.h>
  46 #include <asm/io.h>
  47 #include <asm/dma.h>
  48 #include <asm/bitops.h>
  49 #include <asm/irq.h>
  50 
  51 #include <linux/blk.h>
  52 #include "scsi.h"
  53 #include "hosts.h"
  54 #include "sd.h"
  55 
  56 #include "NCR53c406a.h"
  57 
  58 /* ============================================================= */
  59 
  60 #define WATCHDOG 5000000
  61 
  62 #define SYNC_MODE 0             /* Synchrounous transfer mode */
  63 
  64 #if DEBUG
  65 #undef NCR53C406A_DEBUG
  66 #define NCR53C406A_DEBUG 1
  67 #endif
  68 
  69 #if USE_PIO
  70 #define USE_DMA 0
  71 #else
  72 #define USE_DMA 1
  73 #endif
  74 
  75 /* Default configuration */
  76 #define C1_IMG   0x07           /* ID=7 */
  77 #define C2_IMG   0x48           /* FE SCSI2 */
  78 #if USE_DMA
  79 #define C3_IMG   0x21           /* CDB TE */
  80 #else
  81 #define C3_IMG   0x20           /* CDB */
  82 #endif
  83 #define C4_IMG   0x04           /* ANE */
  84 #define C5_IMG   0xb6           /* AA PI SIE POL */
  85 
  86 #define REG0 (outb(C4_IMG, CONFIG4))
  87 #define REG1 (outb(C5_IMG, CONFIG5))
  88 
  89 #if NCR53C406A_DEBUG
  90 #define DEB(x) x
  91 #else
  92 #define DEB(x)
  93 #endif
  94 
  95 #if VERBOSE_NCR53C406A_DEBUG
  96 #define VDEB(x) x
  97 #else
  98 #define VDEB(x)
  99 #endif
 100 
 101 #define LOAD_DMA_COUNT(count) \
 102   outb(count & 0xff, TC_LSB); \
 103   outb((count >> 8) & 0xff, TC_MSB); \
 104   outb((count >> 16) & 0xff, TC_HIGH);
 105 
 106 /* Chip commands */
 107 #define DMA_OP               0x80
 108 
 109 #define SCSI_NOP             0x00
 110 #define FLUSH_FIFO           0x01
 111 #define CHIP_RESET           0x02
 112 #define SCSI_RESET           0x03
 113 #define RESELECT             0x40
 114 #define SELECT_NO_ATN        0x41
 115 #define SELECT_ATN           0x42
 116 #define SELECT_ATN_STOP      0x43
 117 #define ENABLE_SEL           0x44
 118 #define DISABLE_SEL          0x45
 119 #define SELECT_ATN3          0x46
 120 #define RESELECT3            0x47
 121 #define TRANSFER_INFO        0x10
 122 #define INIT_CMD_COMPLETE    0x11
 123 #define MSG_ACCEPT           0x12
 124 #define TRANSFER_PAD         0x18
 125 #define SET_ATN              0x1a
 126 #define RESET_ATN            0x1b
 127 #define SEND_MSG             0x20
 128 #define SEND_STATUS          0x21
 129 #define SEND_DATA            0x22
 130 #define DISCONN_SEQ          0x23
 131 #define TERMINATE_SEQ        0x24
 132 #define TARG_CMD_COMPLETE    0x25
 133 #define DISCONN              0x27
 134 #define RECV_MSG             0x28
 135 #define RECV_CMD             0x29
 136 #define RECV_DATA            0x2a
 137 #define RECV_CMD_SEQ         0x2b
 138 #define TARGET_ABORT_DMA     0x04
 139 
 140 /*----------------------------------------------------------------*/
 141 /* the following will set the monitor border color (useful to find
 142    where something crashed or gets stuck at */
 143 /* 1 = blue
 144    2 = green
 145    3 = cyan
 146    4 = red
 147    5 = magenta
 148    6 = yellow
 149    7 = white
 150 */
 151 
 152 #if NCR53C406A_DEBUG
 153 #define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
 154 #else
 155 #define rtrc(i) {}
 156 #endif
 157 /*----------------------------------------------------------------*/
 158 
 159 enum Phase {
 160   idle,
 161   data_out,
 162   data_in,
 163   command_ph,
 164   status_ph,
 165   message_out,
 166   message_in
 167 };
 168 
 169 /* Static function prototypes */
 170 static  void NCR53c406a_intr(int, struct pt_regs *);
 171 static  void internal_done(Scsi_Cmnd *);
 172 static  void wait_intr(void);
 173 static  void chip_init(void);
 174 static  void calc_port_addr(void);
 175 #ifndef IRQ_LEV
 176 static  int  irq_probe(void);
 177 #endif
 178 
 179 /* ================================================================= */
 180 
 181 #if USE_BIOS
 182 static void *bios_base = (void *)0;
 183 #endif
 184 
 185 #if PORT_BASE
 186 static int   port_base = PORT_BASE;
 187 #else
 188 static int   port_base = 0;
 189 #endif
 190 
 191 #if IRQ_LEV
 192 static int   irq_level = IRQ_LEV;
 193 #else
 194 static int   irq_level = -1; /* 0 is 'no irq', so use -1 for 'uninitialized'*/
 195 #endif
 196 
 197 #if USE_DMA
 198 static int   dma_chan = 0;
 199 #endif
 200 
 201 #if USE_PIO
 202 static int   fast_pio = USE_FAST_PIO;
 203 #endif
 204 
 205 static Scsi_Cmnd         *current_SC       = NULL;
 206 static volatile int internal_done_flag = 0;
 207 static volatile int internal_done_errcode = 0;
 208 static char info_msg[256];
 209 
 210 /* ================================================================= */
 211 
 212 /* possible BIOS locations */
 213 #if USE_BIOS
 214 static void *addresses[] = {
 215   (void *)0xd8000,
 216   (void *)0xc8000
 217 };
 218 #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
 219 #endif USE_BIOS
 220                        
 221 /* possible i/o port addresses */
 222 static unsigned short ports[] = { 0x230, 0x330 };
 223 #define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
 224 
 225 /* possible interrupt channels */
 226 static unsigned short intrs[] = { 10, 11, 12, 15 };
 227 #define INTR_COUNT (sizeof( intrs ) / sizeof( unsigned short ))
 228 
 229 /* signatures for NCR 53c406a based controllers */
 230 #if USE_BIOS
 231 struct signature {
 232   char *signature;
 233   int  sig_offset;
 234   int  sig_length;
 235 } signatures[] = {
 236   /*          1         2         3         4         5         6 */
 237   /* 123456789012345678901234567890123456789012345678901234567890 */
 238   { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 },
 239 };
 240 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
 241 #endif USE_BIOS
 242 
 243 /* ============================================================ */
 244 
 245 /* Control Register Set 0 */
 246 static int TC_LSB;              /* transfer counter lsb         */
 247 static int TC_MSB;              /* transfer counter msb */
 248 static int SCSI_FIFO;           /* scsi fifo register   */
 249 static int CMD_REG;             /* command register             */
 250 static int STAT_REG;            /* status register              */
 251 static int DEST_ID;             /* selection/reselection bus id */
 252 static int INT_REG;             /* interrupt status register    */
 253 static int SRTIMOUT;            /* select/reselect timeout reg  */
 254 static int SEQ_REG;             /* sequence step register       */
 255 static int SYNCPRD;             /* synchronous transfer period  */
 256 static int FIFO_FLAGS;          /* indicates # of bytes in fifo */
 257 static int SYNCOFF;             /* synchronous offset register  */
 258 static int CONFIG1;             /* configuration register       */
 259 static int CLKCONV;             /* clock conversion reg */
 260 /*static int TESTREG;*/         /* test mode register           */
 261 static int CONFIG2;             /* Configuration 2 Register     */
 262 static int CONFIG3;             /* Configuration 3 Register     */
 263 static int CONFIG4;             /* Configuration 4 Register     */
 264 static int TC_HIGH;             /* Transfer Counter High */
 265 /*static int FIFO_BOTTOM;*/     /* Reserve FIFO byte register   */
 266 
 267 /* Control Register Set 1 */
 268 /*static int JUMPER_SENSE;*/    /* Jumper sense port reg (r/w) */
 269 /*static int SRAM_PTR;*/        /* SRAM address pointer reg (r/w) */
 270 /*static int SRAM_DATA;*/       /* SRAM data register (r/w) */
 271 static int PIO_FIFO;            /* PIO FIFO registers (r/w) */
 272 /*static int PIO_FIFO1;*/       /*  */
 273 /*static int PIO_FIFO2;*/       /*  */
 274 /*static int PIO_FIFO3;*/       /*  */
 275 static int PIO_STATUS;          /* PIO status (r/w) */
 276 /*static int ATA_CMD;*/         /* ATA command/status reg (r/w) */
 277 /*static int ATA_ERR;*/         /* ATA features/error register (r/w)*/
 278 static int PIO_FLAG;            /* PIO flag interrupt enable (r/w) */
 279 static int CONFIG5;             /* Configuration 5 register (r/w) */
 280 /*static int SIGNATURE;*/       /* Signature Register (r) */
 281 /*static int CONFIG6;*/         /* Configuration 6 register (r) */
 282 
 283 /* ============================================================== */
 284 
 285 #if USE_DMA
 286 static __inline__ int 
 287 NCR53c406a_dma_setup (unsigned char *ptr, 
     /* [previous][next][first][last][top][bottom][index][help] */
 288                       unsigned int count, 
 289                       unsigned char mode) {
 290   unsigned limit;
 291   unsigned long flags = 0;
 292 
 293   VDEB(printk("dma: before count=%d   ", count));
 294   if (dma_chan <=3) {
 295     if (count > 65536)
 296       count = 65536;
 297     limit = 65536 - (((unsigned) ptr) & 0xFFFF);
 298   } else {
 299     if (count > (65536<<1)) 
 300       count = (65536<<1);
 301     limit = (65536<<1) - (((unsigned) ptr) & 0x1FFFF);
 302   }
 303   
 304   if (count > limit) count = limit;
 305   
 306   VDEB(printk("after count=%d\n", count));
 307   if ((count & 1) || (((unsigned) ptr) & 1))
 308     panic ("NCR53c406a: attempted unaligned DMA transfer\n"); 
 309 
 310   save_flags(flags);
 311   cli();
 312   disable_dma(dma_chan);
 313   clear_dma_ff(dma_chan);
 314   set_dma_addr(dma_chan, (long) ptr);
 315   set_dma_count(dma_chan, count);
 316   set_dma_mode(dma_chan, mode);
 317   enable_dma(dma_chan);
 318   restore_flags(flags);
 319 
 320   return count;
 321 }
 322      
 323 static __inline__ int 
 324 NCR53c406a_dma_write(unsigned char *src, unsigned int count) {
     /* [previous][next][first][last][top][bottom][index][help] */
 325   return NCR53c406a_dma_setup (src, count, DMA_MODE_WRITE);
 326 }
 327 
 328 static __inline__ int 
 329 NCR53c406a_dma_read(unsigned char *src, unsigned int count) {
     /* [previous][next][first][last][top][bottom][index][help] */
 330   return NCR53c406a_dma_setup (src, count, DMA_MODE_READ);
 331 }
 332 
 333 static __inline__ int 
 334 NCR53c406a_dma_residual (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 335   register int tmp;
 336   unsigned long flags = 0;
 337   save_flags(flags);
 338   cli();
 339   clear_dma_ff(dma_chan);
 340   tmp = get_dma_residue(dma_chan);
 341   restore_flags(flags);
 342 
 343   return tmp;
 344 }
 345 #endif USE_DMA
 346 
 347 #if USE_PIO
 348 static __inline__ int NCR53c406a_pio_read(unsigned char *request, 
     /* [previous][next][first][last][top][bottom][index][help] */
 349                                           unsigned int reqlen) 
 350 {
 351   int   i;
 352   int   len;    /* current scsi fifo size */
 353   unsigned long flags = 0;
 354 
 355   REG1;
 356   while (reqlen) {
 357     i = inb(PIO_STATUS);
 358 /*    VDEB(printk("pio_status=%x\n", i)); */
 359     if (i & 0x80) 
 360       return 0;
 361 
 362     switch( i & 0x1e ) {
 363     default:
 364     case 0x10:
 365       len=0; break;
 366     case 0x0:
 367       len=1; break;
 368     case 0x8:
 369       len=42; break;
 370     case 0xc:
 371       len=84; break;
 372     case 0xe:
 373       len=128; break;
 374     }
 375 
 376     if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occured */
 377       return 0;
 378     }
 379 
 380     if (len) {
 381       if( len > reqlen ) 
 382         len = reqlen;
 383 
 384       save_flags(flags);
 385       cli();
 386       if( fast_pio && len > 3 ) { 
 387         insl(PIO_FIFO,request,len>>2); 
 388         request += len & 0xfc; 
 389         reqlen -= len & 0xfc; 
 390       } 
 391       else { 
 392         while(len--) {
 393           *request++ = inb(PIO_FIFO);
 394           reqlen--;
 395         }
 396       }
 397       restore_flags(flags);
 398     }
 399   }
 400   return 0;
 401 }
 402 
 403 static __inline__ int NCR53c406a_pio_write(unsigned char *request,
     /* [previous][next][first][last][top][bottom][index][help] */
 404                                            unsigned int reqlen) 
 405 {
 406   int   i = 0;
 407   int   len;    /* current scsi fifo size */
 408   unsigned long flags = 0;
 409 
 410   REG1;
 411   while (reqlen && !(i&0x40)) {
 412     i = inb(PIO_STATUS);
 413 /*    VDEB(printk("pio_status=%x\n", i)); */
 414     if (i & 0x80)               /* error */
 415       return 0;
 416     
 417     switch( i & 0x1e ) {
 418     case 0x10:
 419       len=128; break;
 420     case 0x0:
 421       len=84; break;
 422     case 0x8:
 423       len=42; break;
 424     case 0xc:
 425       len=1; break;
 426     default:
 427     case 0xe:
 428       len=0; break;
 429     }
 430 
 431     if (len) {
 432       if( len > reqlen ) 
 433         len = reqlen;
 434       
 435       save_flags(flags);
 436       cli();
 437       if( fast_pio && len > 3 ) { 
 438         outsl(PIO_FIFO,request,len>>2); 
 439         request += len & 0xfc; 
 440         reqlen -= len & 0xfc; 
 441       } 
 442       else { 
 443         while(len--) {
 444           outb(*request++, PIO_FIFO);
 445           reqlen--;
 446         }
 447       }
 448       restore_flags(flags);
 449     }
 450   }
 451   return 0;
 452 }
 453 #endif USE_PIO
 454 
 455 int 
 456 NCR53c406a_detect(Scsi_Host_Template * tpnt){
     /* [previous][next][first][last][top][bottom][index][help] */
 457   struct Scsi_Host *shpnt;
 458 #ifndef PORT_BASE
 459   int i;
 460 #endif
 461   
 462 #if USE_BIOS
 463   int ii, jj;
 464   bios_base = 0;
 465   /* look for a valid signature */
 466   for( ii=0; ii < ADDRESS_COUNT && !bios_base; ii++)
 467     for( jj=0; (jj < SIGNATURE_COUNT) && !bios_base; jj++)
 468       if(!memcmp((void *) addresses[ii]+signatures[jj].sig_offset,
 469                  (void *) signatures[jj].signature,
 470                  (int) signatures[jj].sig_length))
 471         bios_base=addresses[ii];
 472 
 473   if(!bios_base){
 474     printk("NCR53c406a: BIOS signature not found\n");
 475     return 0;
 476   }
 477   
 478   DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base););
 479 #endif USE_BIOS
 480     
 481 #ifdef PORT_BASE
 482   if (check_region(port_base, 0x10)) /* ports already snatched */
 483     port_base = 0;
 484 
 485 #else  /* autodetect */
 486   if (port_base) {              /* LILO override */
 487     if (check_region(port_base, 0x10))
 488       port_base = 0;
 489   }
 490   else {
 491     for(i=0;  i<PORT_COUNT && !port_base; i++){
 492       if(check_region(ports[i], 0x10)){
 493         DEB(printk("NCR53c406a: port %x in use\n", ports[i]));
 494       }
 495       else {
 496         VDEB(printk("NCR53c406a: port %x available\n", ports[i]));
 497         outb(C5_IMG, ports[i] + 0x0d); /* reg set 1 */
 498         if(   (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
 499            && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
 500            && (inb(ports[i] + 0x0e) & 0xf8) == 0x58 ) {
 501           VDEB(printk("NCR53c406a: Sig register valid\n"));
 502           VDEB(printk("port_base=%x\n", port_base));
 503           port_base = ports[i];
 504         }
 505       }
 506     }
 507   }
 508 #endif PORT_BASE
 509 
 510   if(!port_base){               /* no ports found */
 511     printk("NCR53c406a: no available ports found\n");
 512     return 0;
 513   }
 514 
 515   DEB(printk("NCR53c406a detected\n"));
 516   
 517   calc_port_addr();
 518   chip_init();
 519 
 520 #ifndef IRQ_LEV
 521   if (irq_level < 0) {          /* LILO override if >= 0*/
 522     irq_level=irq_probe();
 523     if (irq_level < 0) {                /* Trouble */
 524       printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
 525       return 0;
 526     }
 527   }
 528 #endif
 529 
 530   DEB(printk("NCR53c406a: using port_base %x\n", port_base));
 531   request_region(port_base, 0x10, "NCR53c406a");
 532 
 533   if(irq_level > 0) {
 534     if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a")){
 535       printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);
 536       return 0;
 537     }
 538     tpnt->can_queue = 1;
 539     DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level));
 540   }
 541   else if (irq_level == 0) {
 542     tpnt->can_queue = 0;
 543     DEB(printk("NCR53c406a: No interrupts detected\n"));
 544 #if USE_DMA
 545     printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
 546     return 0;
 547 #endif USE_DMA
 548   }
 549   else {
 550     DEB(printk("NCR53c406a: Shouldn't get here!\n"));
 551     return 0;
 552   }
 553 
 554 #if USE_DMA
 555   dma_chan = DMA_CHAN;
 556   if(request_dma(dma_chan, "NCR53c406a") != 0){
 557     printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan);
 558     return 0;
 559   }
 560 
 561   DEB(printk("Allocated DMA channel %d\n", dma_chan));
 562 #endif USE_DMA 
 563 
 564   tpnt->present = 1;
 565 
 566   shpnt = scsi_register(tpnt, 0);
 567   shpnt->irq = irq_level;
 568   shpnt->io_port = port_base;
 569   shpnt->n_io_port = 0x10;
 570 #if USE_DMA
 571   shpnt->dma = dma_chan;
 572 #endif
 573 
 574 #if USE_DMA
 575   sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.", port_base, irq_level, dma_chan);
 576 #else
 577   sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ? "fast" : "slow");
 578 #endif
 579 
 580   return (tpnt->present);
 581 }
 582 
 583 /* called from init/main.c */
 584 void NCR53c406a_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 585 {
 586   static size_t setup_idx = 0;
 587   size_t i;
 588   
 589   DEB(printk("NCR53c406a: Setup called\n"););
 590   
 591   if (setup_idx >= PORT_COUNT - 1) {
 592     printk("NCR53c406a: Setup called too many times.  Bad LILO params?\n");
 593     return;
 594   }
 595   if (ints[0] < 1 || ints[0] > 3) {
 596     printk("NCR53c406a: Malformed command line\n");
 597     printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");
 598     return;
 599   }
 600   for (i = 0; i < PORT_COUNT && !port_base; i++)
 601     if (ports[i] == ints[1]) {
 602       port_base = ints[1];
 603       DEB(printk("NCR53c406a: Specified port_base 0x%X\n", port_base);)
 604     }
 605   if (!port_base) {
 606     printk("NCR53c406a: Invalid PORTBASE 0x%X specified\n", ints[1]);
 607     return;
 608   }
 609   
 610   if (ints[0] > 1) {
 611     if (ints[2] == 0) {
 612       irq_level = 0;
 613       DEB(printk("NCR53c406a: Specified irq %d\n", irq_level);)
 614     }
 615     else
 616       for (i = 0; i < INTR_COUNT && irq_level < 0; i++)
 617         if (intrs[i] == ints[2]) {
 618           irq_level = ints[2];
 619           DEB(printk("NCR53c406a: Specified irq %d\n", port_base);)
 620         }
 621     if (irq_level < 0)
 622       printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]);
 623   }
 624 
 625   if (ints[0] > 2)
 626     fast_pio = ints[3];
 627 
 628   DEB(printk("NCR53c406a: port_base=0x%X, irq=%d, fast_pio=%d\n", port_base, irq_level, fast_pio);)
 629 }
 630 
 631 const char* 
 632 NCR53c406a_info(struct Scsi_Host *SChost){
     /* [previous][next][first][last][top][bottom][index][help] */
 633   DEB(printk("NCR53c406a_info called\n"));
 634   return (info_msg);
 635 }
 636 
 637 static void internal_done(Scsi_Cmnd *SCpnt) {
     /* [previous][next][first][last][top][bottom][index][help] */
 638   internal_done_errcode = SCpnt->result;
 639   ++internal_done_flag;
 640 }
 641 
 642 
 643 static void wait_intr() {
     /* [previous][next][first][last][top][bottom][index][help] */
 644   int i = jiffies + WATCHDOG;
 645 
 646   while(i>jiffies && !(inb(STAT_REG)&0xe0)) /* wait for a pseudo-interrupt */
 647     barrier();
 648 
 649   if (i <= jiffies) {           /* Timed out */
 650     rtrc(0);
 651     current_SC->result = DID_TIME_OUT << 16;
 652     current_SC->SCp.phase = idle;
 653     current_SC->scsi_done(current_SC);
 654     return;
 655   }
 656   
 657   NCR53c406a_intr(0, NULL);
 658 }
 659 
 660 int NCR53c406a_command(Scsi_Cmnd *SCpnt){
     /* [previous][next][first][last][top][bottom][index][help] */
 661   DEB(printk("NCR53c406a_command called\n"));
 662   NCR53c406a_queue(SCpnt, internal_done);
 663   if(irq_level)
 664     while (!internal_done_flag);
 665   else                          /* interrupts not supported */
 666     while (!internal_done_flag)
 667       wait_intr();
 668   
 669   internal_done_flag = 0;
 670   return internal_done_errcode;
 671 }
 672 
 673 
 674 int 
 675 NCR53c406a_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){
     /* [previous][next][first][last][top][bottom][index][help] */
 676   int i;
 677   unsigned long flags = 0;
 678 
 679   VDEB(printk("NCR53c406a_queue called\n"));
 680   DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", 
 681          SCpnt->cmnd[0],
 682          SCpnt->cmd_len,
 683          SCpnt->target, 
 684          SCpnt->lun,  
 685          SCpnt->request_bufflen));
 686 
 687 #if 0
 688   VDEB(for(i=0; i<SCpnt->cmd_len; i++)
 689     printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));
 690   VDEB(printk("\n"));
 691 #endif
 692 
 693   current_SC = SCpnt;
 694   current_SC->scsi_done = done;
 695   current_SC->SCp.phase = command_ph;
 696   current_SC->SCp.Status = 0;
 697   current_SC->SCp.Message = 0;
 698   
 699   save_flags(flags);
 700   cli();
 701   REG0;
 702   outb(SCpnt->target, DEST_ID); /* set destination */
 703   outb(FLUSH_FIFO, CMD_REG);    /* reset the fifos */
 704   
 705   for(i=0; i<SCpnt->cmd_len; i++){
 706     outb(SCpnt->cmnd[i], SCSI_FIFO);
 707   }
 708   outb(SELECT_NO_ATN, CMD_REG);
 709   restore_flags(flags);
 710 
 711   rtrc(1);
 712   return 0;
 713 }
 714 
 715 int
 716 NCR53c406a_abort(Scsi_Cmnd *SCpnt){
     /* [previous][next][first][last][top][bottom][index][help] */
 717   DEB(printk("NCR53c406a_abort called\n"));
 718   return SCSI_ABORT_SNOOZE;     /* Don't know how to abort */
 719 }
 720 
 721 int 
 722 NCR53c406a_reset(Scsi_Cmnd *SCpnt){
     /* [previous][next][first][last][top][bottom][index][help] */
 723   DEB(printk("NCR53c406a_reset called\n"));
 724   outb(C4_IMG, CONFIG4); /* Select reg set 0 */
 725   outb(CHIP_RESET, CMD_REG);
 726   outb(SCSI_NOP, CMD_REG);      /* required after reset */
 727   outb(SCSI_RESET, CMD_REG);
 728   chip_init();
 729 
 730   rtrc(2);
 731   if (irq_level)
 732     return SCSI_RESET_PENDING;  /* should get an interrupt */
 733   else
 734     return SCSI_RESET_WAKEUP;   /* won't get any interrupts */
 735 }
 736 
 737 int 
 738 NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){
     /* [previous][next][first][last][top][bottom][index][help] */
 739   int size;
 740 
 741   DEB(printk("NCR53c406a_biosparm called\n"));
 742 
 743   size = disk->capacity;
 744   info_array[0] = 64;   /* heads */
 745   info_array[1] = 32;   /* sectors */
 746   info_array[2] = size>>11;  /* cylinders */
 747   if (info_array[2] > 1024) {   /* big disk */
 748     info_array[0] = 255;
 749     info_array[1] = 63;
 750     info_array[2] = size / (255*63);
 751   }
 752   return 0;
 753 }
 754 
 755 static void
 756 NCR53c406a_intr(int unused, struct pt_regs *regs){
     /* [previous][next][first][last][top][bottom][index][help] */
 757   DEB(unsigned char fifo_size;)
 758   DEB(unsigned char seq_reg;)
 759   unsigned char status, int_reg;
 760   unsigned long flags = 0;
 761 #if USE_PIO
 762   unsigned char pio_status; 
 763   struct scatterlist *sglist;
 764   unsigned int sgcount;
 765 #endif
 766 
 767   VDEB(printk("NCR53c406a_intr called\n"));
 768 
 769   save_flags(flags);
 770   cli();
 771 #if USE_PIO
 772   REG1;
 773   pio_status = inb(PIO_STATUS);
 774 #endif
 775   REG0;
 776   status = inb(STAT_REG);
 777   DEB(seq_reg = inb(SEQ_REG));
 778   int_reg = inb(INT_REG);
 779   DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f);
 780   restore_flags(flags);
 781 
 782 #if NCR53C406A_DEBUG
 783   printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x", 
 784          status, seq_reg, int_reg, fifo_size);
 785 #if (USE_DMA)
 786   printk("\n");
 787 #else
 788   printk(", pio=%02x\n", pio_status);
 789 #endif USE_DMA
 790 #endif NCR53C406A_DEBUG
 791 
 792   if(int_reg & 0x80){ /* SCSI reset intr */
 793     rtrc(3);
 794     DEB(printk("NCR53c406a: reset intr received\n"));
 795     current_SC->SCp.phase = idle;
 796     current_SC->result = DID_RESET << 16;
 797     current_SC->scsi_done(current_SC);
 798     return;
 799   }
 800 
 801 #if USE_PIO
 802   if(pio_status & 0x80) {
 803     printk("NCR53C406A: Warning: PIO error!\n");
 804     current_SC->SCp.phase = idle;
 805     current_SC->result = DID_ERROR << 16;
 806     current_SC->scsi_done(current_SC);
 807     return;
 808   }
 809 #endif USE_PIO
 810 
 811   if(status & 0x20) {           /* Parity error */
 812     printk("NCR53c406a: Warning: parity error!\n");
 813     current_SC->SCp.phase = idle;
 814     current_SC->result = DID_PARITY << 16;
 815     current_SC->scsi_done(current_SC);
 816     return;
 817   }
 818 
 819   if(status & 0x40) {           /* Gross error */
 820     printk("NCR53c406a: Warning: gross error!\n");
 821     current_SC->SCp.phase = idle;
 822     current_SC->result = DID_ERROR << 16;
 823     current_SC->scsi_done(current_SC);
 824     return;
 825   }
 826 
 827   if(int_reg & 0x20){           /* Disconnect */
 828     DEB(printk("NCR53c406a: disconnect intr received\n"));
 829     if(current_SC->SCp.phase != message_in){ /* Unexpected disconnect */
 830       current_SC->result = DID_NO_CONNECT << 16;
 831       }
 832     else{  /* Command complete, return status and message */
 833       current_SC->result = (current_SC->SCp.Status & 0xff) 
 834         | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
 835     }
 836   
 837     rtrc(0);
 838     current_SC->SCp.phase = idle;
 839     current_SC->scsi_done( current_SC );
 840     return;
 841   }
 842   
 843   switch(status & 0x07){        /* scsi phase */
 844   case 0x00:                    /* DATA-OUT */
 845     if(int_reg & 0x10){         /* Target requesting info transfer */
 846       rtrc(5);
 847       current_SC->SCp.phase = data_out;
 848       VDEB(printk("NCR53c406a: Data-Out phase\n"));
 849       outb(FLUSH_FIFO, CMD_REG);
 850       LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
 851 #if USE_DMA                     /* No s/g support for DMA */
 852       NCR53c406a_dma_write(current_SC->request_buffer, 
 853                            current_SC->request_bufflen);
 854 #endif USE_DMA
 855       outb(TRANSFER_INFO | DMA_OP, CMD_REG); 
 856 #if USE_PIO
 857       if (!current_SC->use_sg)  /* Don't use scatter-gather */
 858         NCR53c406a_pio_write(current_SC->request_buffer, 
 859                              current_SC->request_bufflen);
 860       else {                    /* use scatter-gather */
 861         sgcount = current_SC->use_sg;
 862         sglist = current_SC->request_buffer;
 863         while( sgcount-- ) {
 864           NCR53c406a_pio_write(sglist->address, sglist->length);
 865           sglist++;
 866         }
 867       }
 868       REG0;
 869 #endif USE_PIO
 870     }
 871     break;
 872       
 873   case 0x01:                    /* DATA-IN */
 874     if(int_reg & 0x10){         /* Target requesting info transfer */
 875       rtrc(6);
 876       current_SC->SCp.phase = data_in;
 877       VDEB(printk("NCR53c406a: Data-In phase\n"));
 878       outb(FLUSH_FIFO, CMD_REG);
 879       LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
 880 #if USE_DMA                     /* No s/g support for DMA */
 881       NCR53c406a_dma_read(current_SC->request_buffer, 
 882                           current_SC->request_bufflen);
 883 #endif USE_DMA
 884       outb(TRANSFER_INFO | DMA_OP, CMD_REG); 
 885 #if USE_PIO
 886       if (!current_SC->use_sg)  /* Don't use scatter-gather */
 887         NCR53c406a_pio_read(current_SC->request_buffer, 
 888                             current_SC->request_bufflen);
 889       else {                    /* Use scatter-gather */
 890         sgcount = current_SC->use_sg;
 891         sglist = current_SC->request_buffer;
 892         while( sgcount-- ) {
 893           NCR53c406a_pio_read(sglist->address, sglist->length);
 894           sglist++;
 895         }
 896       }
 897       REG0;
 898 #endif USE_PIO
 899     }
 900     break;
 901     
 902   case 0x02:                    /* COMMAND */
 903     current_SC->SCp.phase = command_ph;
 904     printk("NCR53c406a: Warning: Unknown interupt occured in command phase!\n");
 905     break;
 906     
 907   case 0x03:                    /* STATUS */
 908     rtrc(7);
 909     current_SC->SCp.phase = status_ph;
 910     VDEB(printk("NCR53c406a: Status phase\n"));
 911 #if 0
 912 #if VERBOSE_NCR53C406A_DEBUG
 913     printk("request_buffer=");
 914     for(i=0; i<current_SC->request_bufflen && i<256; i++)
 915       printk("%02x ", *((unsigned char*)current_SC->request_buffer + i));
 916     printk("\n");
 917 #if USE_DMA
 918     printk("dma residue = %d\n", NCR53c406a_dma_residual());
 919 #endif USE_DMA
 920 #endif VERBOSE_NCR53C406A_DEBUG
 921 #endif
 922     
 923     outb(FLUSH_FIFO, CMD_REG);
 924     outb(INIT_CMD_COMPLETE, CMD_REG);
 925     break;
 926     
 927   case 0x04:                    /* Reserved */
 928   case 0x05:                    /* Reserved */
 929     printk("NCR53c406a: WARNING: Reserved phase!!!\n");
 930     break;
 931     
 932   case 0x06:                    /* MESSAGE-OUT */
 933     DEB(printk("NCR53c406a: Message-Out phase\n"));
 934     current_SC->SCp.phase = message_out;
 935     outb(SET_ATN, CMD_REG);     /* Reject the message */
 936     outb(MSG_ACCEPT, CMD_REG);
 937     break;
 938     
 939   case 0x07:                    /* MESSAGE-IN */
 940     rtrc(4);
 941     VDEB(printk("NCR53c406a: Message-In phase\n"));
 942     current_SC->SCp.phase = message_in;
 943     
 944     current_SC->SCp.Status = inb(SCSI_FIFO);    
 945     current_SC->SCp.Message = inb(SCSI_FIFO);
 946     
 947     VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f));
 948     DEB(printk("Status = %02x  Message = %02x\n", 
 949                current_SC->SCp.Status, current_SC->SCp.Message));
 950     
 951     if(current_SC->SCp.Message == SAVE_POINTERS || 
 952        current_SC->SCp.Message == DISCONNECT) {
 953       outb(SET_ATN, CMD_REG);   /* Reject message */
 954       DEB(printk("Discarding SAVE_POINTERS message\n"));
 955     }
 956     outb(MSG_ACCEPT, CMD_REG);
 957     break;
 958   }
 959 }
 960 
 961 #ifndef IRQ_LEV
 962 static int irq_probe()
     /* [previous][next][first][last][top][bottom][index][help] */
 963 {
 964   int irqs, irq;
 965   int i;
 966 
 967   inb(INT_REG);                 /* clear the interrupt register */
 968   sti();
 969   irqs = probe_irq_on();
 970 
 971   /* Invalid command will cause an interrupt */
 972   REG0;
 973   outb(0xff, CMD_REG);
 974 
 975   /* Wait for the interrupt to occur */
 976   i = jiffies + WATCHDOG;
 977   while(i > jiffies && !(inb(STAT_REG) & 0x80))
 978     barrier();
 979   if (i <= jiffies) {           /* Timed out, must be hardware trouble */
 980     probe_irq_off(irqs);
 981     return -1;
 982   }
 983 
 984   irq = probe_irq_off(irqs);
 985 
 986   /* Kick the chip */
 987   outb(CHIP_RESET, CMD_REG);
 988   outb(SCSI_NOP, CMD_REG);
 989   chip_init();
 990 
 991   return irq;
 992 }
 993 #endif IRQ_LEV
 994 
 995 static void chip_init()
     /* [previous][next][first][last][top][bottom][index][help] */
 996 {
 997   REG1;
 998 #if USE_DMA
 999   outb(0x00, PIO_STATUS);
1000 #else  /* USE_PIO */
1001   outb(0x01, PIO_STATUS);
1002 #endif
1003   outb(0x00, PIO_FLAG);
1004   
1005   outb(C4_IMG, CONFIG4);        /* REG0; */
1006   outb(C3_IMG, CONFIG3);
1007   outb(C2_IMG, CONFIG2);
1008   outb(C1_IMG, CONFIG1);
1009   
1010   outb(0x05, CLKCONV);          /* clock conversion factor */
1011   outb(0x9C, SRTIMOUT);         /* Selection timeout */
1012   outb(0x05, SYNCPRD);          /* Synchronous transfer period */
1013   outb(SYNC_MODE, SYNCOFF);             /* synchronous mode */  
1014 }
1015 
1016 void calc_port_addr()
     /* [previous][next][first][last][top][bottom][index][help] */
1017 {
1018 /* Control Register Set 0 */
1019 TC_LSB          = (port_base+0x00);
1020 TC_MSB          = (port_base+0x01);
1021 SCSI_FIFO       = (port_base+0x02);
1022 CMD_REG         = (port_base+0x03);
1023 STAT_REG        = (port_base+0x04);
1024 DEST_ID         = (port_base+0x04);
1025 INT_REG         = (port_base+0x05);
1026 SRTIMOUT        = (port_base+0x05);
1027 SEQ_REG         = (port_base+0x06);
1028 SYNCPRD         = (port_base+0x06);
1029 FIFO_FLAGS      = (port_base+0x07);
1030 SYNCOFF         = (port_base+0x07);
1031 CONFIG1         = (port_base+0x08);
1032 CLKCONV         = (port_base+0x09);
1033 /* TESTREG              = (port_base+0x0A); */
1034 CONFIG2         = (port_base+0x0B);
1035 CONFIG3         = (port_base+0x0C);
1036 CONFIG4         = (port_base+0x0D);
1037 TC_HIGH         = (port_base+0x0E);
1038 /* FIFO_BOTTOM  = (port_base+0x0F); */
1039 
1040 /* Control Register Set 1 */
1041 /* JUMPER_SENSE = (port_base+0x00);*/
1042 /* SRAM_PTR     = (port_base+0x01);*/
1043 /* SRAM_DATA    = (port_base+0x02);*/
1044 PIO_FIFO        = (port_base+0x04);
1045 /* PIO_FIFO1    = (port_base+0x05);*/
1046 /* PIO_FIFO2    = (port_base+0x06);*/
1047 /* PIO_FIFO3    = (port_base+0x07);*/
1048 PIO_STATUS      = (port_base+0x08);
1049 /* ATA_CMD              = (port_base+0x09);*/
1050 /* ATA_ERR              = (port_base+0x0A);*/
1051 PIO_FLAG        = (port_base+0x0B);
1052 CONFIG5         = (port_base+0x0D);
1053 /* SIGNATURE    = (port_base+0x0E);*/
1054 /* CONFIG6              = (port_base+0x0F);*/
1055 }
1056 
1057 #ifdef MODULE
1058 /* Eventually this will go into an include file, but this will be later */
1059 Scsi_Host_Template driver_template = NCR53c406a;
1060 
1061 #include "scsi_module.c"
1062 #endif

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