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

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