Annotation of Gnu-Mach/linux/src/drivers/scsi/NCR53c406a.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  *  NCR53c406.c
                      3:  *  Low-level SCSI driver for NCR53c406a chip.
                      4:  *  Copyright (C) 1994, 1995, 1996 Normunds Saumanis ([email protected])
                      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, 
                    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) {
                    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) {
                    336:     return NCR53c406a_dma_setup (src, count, DMA_MODE_READ);
                    337: }
                    338: 
                    339: static __inline__ int 
                    340: NCR53c406a_dma_residual (void) {
                    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, 
                    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,
                    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){
                    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)
                    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){
                    643:     DEB(printk("NCR53c406a_info called\n"));
                    644:     return (info_msg);
                    645: }
                    646: 
                    647: static void internal_done(Scsi_Cmnd *SCpnt) {
                    648:     internal_done_errcode = SCpnt->result;
                    649:     ++internal_done_flag;
                    650: }
                    651: 
                    652: 
                    653: static void wait_intr() {
                    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){
                    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 *)){
                    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){
                    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, unsigned int flags){
                    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){
                    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){
                    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()
                    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()
                    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()
                   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:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.