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

1.1       root        1: /*
                      2:  * Generic Generic NCR5380 driver
                      3:  *     
                      4:  * Copyright 1993, Drew Eckhardt
                      5:  *     Visionary Computing
                      6:  *     (Unix and Linux consulting and custom programming)
                      7:  *     [email protected]
                      8:  *      +1 (303) 440-4894
                      9:  *
                     10:  * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
                     11:  *    [email protected]
                     12:  *
                     13:  * ALPHA RELEASE 1. 
                     14:  *
                     15:  * For more information, please consult 
                     16:  *
                     17:  * NCR 5380 Family
                     18:  * SCSI Protocol Controller
                     19:  * Databook
                     20:  *
                     21:  * NCR Microelectronics
                     22:  * 1635 Aeroplaza Drive
                     23:  * Colorado Springs, CO 80916
                     24:  * 1+ (719) 578-3400
                     25:  * 1+ (800) 334-5454
                     26:  */
                     27: 
                     28: /* 
                     29:  * TODO : flesh out DMA support, find some one actually using this (I have
                     30:  *     a memory mapped Trantor board that works fine)
                     31:  */
                     32: 
                     33: /*
                     34:  * Options :
                     35:  *
                     36:  * PARITY - enable parity checking.  Not supported.
                     37:  *
                     38:  * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
                     39:  *
                     40:  * USLEEP - enable support for devices that don't disconnect.  Untested.
                     41:  *
                     42:  * The card is detected and initialized in one of several ways : 
                     43:  * 1.  With command line overrides - NCR5380=port,irq may be 
                     44:  *     used on the LILO command line to override the defaults.
                     45:  *
                     46:  * 2.  With the GENERIC_NCR5380_OVERRIDE compile time define.  This is 
                     47:  *     specified as an array of address, irq, dma, board tuples.  Ie, for
                     48:  *     one board at 0x350, IRQ5, no dma, I could say  
                     49:  *     -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
                     50:  * 
                     51:  * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an 
                     52:  *     IRQ line if overridden on the command line.
                     53:  *
                     54:  * 3.  When included as a module, with arguments passed on the command line:
                     55:  *         ncr_irq=xx  the interrupt
                     56:  *         ncr_addr=xx  the port or base address (for port or memory
                     57:  *                     mapped, resp.)
                     58:  *         ncr_dma=xx  the DMA
                     59:  *         ncr_5380=1  to set up for a NCR5380 board
                     60:  *         ncr_53c400=1        to set up for a NCR53C400 board
                     61:  *     e.g.
                     62:  *     modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
                     63:  *       for a port mapped NCR5380 board or
                     64:  *     modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
                     65:  *       for a memory mapped NCR53C400 board with interrupts disabled.
                     66:  * 
                     67:  * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an 
                     68:  *     IRQ line if overridden on the command line.
                     69:  *     
                     70:  */
                     71:  
                     72: /*
                     73:  * $Log: g_NCR5380.c,v $
                     74:  * Revision 1.1  1999/04/26 05:54:33  tb
                     75:  * 1998-11-30  OKUJI Yoshinori  <[email protected]>
                     76:  *
                     77:  *     Clean up linux emulation code to make it architecture-independent
                     78:  *     as much as possible.
                     79:  *
                     80:  *     * linux: Renamed from linuxdev.
                     81:  *     * Makefile.in (objfiles): Add linux.o instead of linuxdev.o.
                     82:  *     (MAKE): New variable. Used for the linux.o target.
                     83:  *     * configure.in: Add AC_CHECK_TOOL(MAKE, make).
                     84:  *     * i386/i386/spl.h: Include <i386/ipl.h>, for compatibility with
                     85:  *     OSF Mach 3.0. Suggested by Elgin Lee <[email protected]>.
                     86:  *     * linux/src: Renamed from linux/linux.
                     87:  *     * linux/dev: Renamed from linux/mach.
                     88:  *     * linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h,
                     89:  *     instead of mach/include/linux/autoconf.h.
                     90:  *     * Makefile.in (all): Target ../linux.o instead of ../linuxdev.o.
                     91:  *     * linux/dev/drivers/block/genhd.c: Include <machine/spl.h> instead
                     92:  *     of <i386/ipl.h>.
                     93:  *     * linux/dev/drivers/net/auto_irq.c: Remove unneeded header files,
                     94:  *     <i386/ipl.h> and <i386/pic.h>.
                     95:  *     * linux/dev/init/main.c: Many i386-dependent codes moved to ...
                     96:  *     * linux/dev/arch/i386/irq.c: ... here.
                     97:  *     * linux/dev/arch/i386/setup.c: New file.
                     98:  *     * linux/dev/arch/i386/linux_emul.h: Likewise.
                     99:  *     * linux/dev/arch/i386/glue/timer.c: Merged into sched.c.
                    100:  *     * linux/dev/arch/i386/glue/sched.c: Include <machine/spl.h> instead
                    101:  *     of <i386/ipl.h>, and moved to ...
                    102:  *     * linux/dev/kernel/sched.c: ... here.
                    103:  *     * linux/dev/arch/i386/glue/block.c: Include <machine/spl.h> and
                    104:  *     <linux_emul.h>, instead of i386-dependent header files, and
                    105:  *     moved to ...
                    106:  *     * linux/dev/glue/blocl.c: ... here.
                    107:  *     * linux/dev/arch/i386/glue/net.c: Include <machine/spl.h> and
                    108:  *     <linux_emul.h>, instead of i386-dependent header files, and
                    109:  *     moved to ...
                    110:  *     * linux/dev/glue/net.c: ... here.
                    111:  *     * linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ...
                    112:  *     * linux/dev/glue/misc.c: ... here.
                    113:  *     * linux/dev/arch/i386/glue/kmem.c: Moved to ...
                    114:  *     * linux/dev/glue/kmem.c: ... here.
                    115:  *
                    116:  */
                    117: 
                    118: #define AUTOPROBE_IRQ
                    119: #define AUTOSENSE
                    120: 
                    121: #include <linux/config.h>
                    122: 
                    123: #ifdef CONFIG_SCSI_GENERIC_NCR53C400
                    124: #define NCR53C400_PSEUDO_DMA 1
                    125: #define PSEUDO_DMA
                    126: #define NCR53C400
                    127: #define NCR5380_STATS
                    128: #undef NCR5380_STAT_LIMIT
                    129: #endif
                    130: #if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM)
                    131: #error You can not configure the Generic NCR 5380 SCSI Driver for memory mapped I/O and port mapped I/O at the same time (yet)
                    132: #endif
                    133: #if !defined(CONFIG_SCSI_G_NCR5380_PORT) && !defined(CONFIG_SCSI_G_NCR5380_MEM)
                    134: #error You must configure the Generic NCR 5380 SCSI Driver for one of memory mapped I/O and port mapped I/O.
                    135: #endif
                    136: 
                    137: #include <asm/system.h>
                    138: #include <asm/io.h>
                    139: #include <linux/signal.h>
                    140: #include <linux/sched.h>
                    141: #include <linux/blk.h>
                    142: #include "scsi.h"
                    143: #include "hosts.h"
                    144: #include "g_NCR5380.h"
                    145: #include "NCR5380.h"
                    146: #include "constants.h"
                    147: #include "sd.h"
                    148: #include<linux/stat.h>
                    149: 
                    150: struct proc_dir_entry proc_scsi_g_ncr5380 = {
                    151:     PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380",
                    152:     S_IFDIR | S_IRUGO | S_IXUGO, 2
                    153: };
                    154: 
                    155: #define NCR_NOT_SET 0
                    156: static int ncr_irq=NCR_NOT_SET;
                    157: static int ncr_dma=NCR_NOT_SET;
                    158: static int ncr_addr=NCR_NOT_SET;
                    159: static int ncr_5380=NCR_NOT_SET;
                    160: static int ncr_53c400=NCR_NOT_SET;
                    161: 
                    162: static struct override {
                    163:        NCR5380_implementation_fields;
                    164:     int irq;
                    165:     int dma;
                    166:     int board; /* Use NCR53c400, Ricoh, etc. extensions ? */
                    167: } overrides 
                    168: #ifdef GENERIC_NCR5380_OVERRIDE 
                    169:     [] = GENERIC_NCR5380_OVERRIDE
                    170: #else
                    171:     [1] = {{0,},};
                    172: #endif
                    173: 
                    174: #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
                    175: 
                    176: /*
                    177:  * Function : static internal_setup(int board, char *str, int *ints)
                    178:  *
                    179:  * Purpose : LILO command line initialization of the overrides array,
                    180:  * 
                    181:  * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board, 
                    182:  *     or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints - 
                    183:  *     array of integer parameters with ints[0] equal to the number of ints.
                    184:  *
                    185:  */
                    186: 
                    187: static void internal_setup(int board, char *str, int *ints) {
                    188:     static int commandline_current = 0;
                    189:     switch (board) {
                    190:     case BOARD_NCR5380:
                    191:        if (ints[0] != 2 && ints[0] != 3) {
                    192:            printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
                    193:            return;
                    194:        }
                    195:     case BOARD_NCR53C400:
                    196:        if (ints[0] != 2) {
                    197:            printk("generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
                    198:            return;
                    199:        }
                    200:     }
                    201: 
                    202:     if (commandline_current < NO_OVERRIDES) {
                    203:        overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
                    204:        overrides[commandline_current].irq = ints[2];
                    205:        if (ints[0] == 3) 
                    206:            overrides[commandline_current].dma = ints[3];
                    207:        else 
                    208:            overrides[commandline_current].dma = DMA_NONE;
                    209:        overrides[commandline_current].board = board;
                    210:            ++commandline_current;
                    211:     }
                    212: }
                    213: 
                    214: /*
                    215:  * Function : generic_NCR5380_setup (char *str, int *ints)
                    216:  *
                    217:  * Purpose : LILO command line initialization of the overrides array,
                    218:  * 
                    219:  * Inputs : str - unused, ints - array of integer parameters with ints[0] 
                    220:  *     equal to the number of ints.
                    221:  */
                    222: 
                    223: void generic_NCR5380_setup (char *str, int *ints) {
                    224:     internal_setup (BOARD_NCR5380, str, ints);
                    225: }
                    226: 
                    227: /*
                    228:  * Function : generic_NCR53C400_setup (char *str, int *ints)
                    229:  *
                    230:  * Purpose : LILO command line initialization of the overrides array,
                    231:  * 
                    232:  * Inputs : str - unused, ints - array of integer parameters with ints[0] 
                    233:  *     equal to the number of ints.
                    234:  */
                    235: 
                    236: void generic_NCR53C400_setup (char *str, int *ints) {
                    237:     internal_setup (BOARD_NCR53C400, str, ints);
                    238: }
                    239: 
                    240: /* 
                    241:  * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
                    242:  *
                    243:  * Purpose : initializes generic NCR5380 driver based on the 
                    244:  *     command line / compile time port and irq definitions.
                    245:  *
                    246:  * Inputs : tpnt - template for this SCSI adapter.
                    247:  * 
                    248:  * Returns : 1 if a host adapter was found, 0 if not.
                    249:  *
                    250:  */
                    251: 
                    252: int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
                    253:     static int current_override = 0;
                    254:     int count;
                    255:     int flags = 0;
                    256:     struct Scsi_Host *instance;
                    257: 
                    258:     if (ncr_irq != NCR_NOT_SET)
                    259:        overrides[0].irq=ncr_irq;
                    260:     if (ncr_dma != NCR_NOT_SET)
                    261:        overrides[0].dma=ncr_dma;
                    262:     if (ncr_addr != NCR_NOT_SET)
                    263:        overrides[0].NCR5380_map_name=(NCR5380_map_type)ncr_addr;
                    264:     if (ncr_5380 != NCR_NOT_SET)
                    265:        overrides[0].board=BOARD_NCR5380;
                    266:     else if (ncr_53c400 != NCR_NOT_SET)
                    267:        overrides[0].board=BOARD_NCR53C400;
                    268: 
                    269:     tpnt->proc_dir = &proc_scsi_g_ncr5380;
                    270: 
                    271:     for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
                    272:        if (!(overrides[current_override].NCR5380_map_name))
                    273:            continue;
                    274: 
                    275:        switch (overrides[current_override].board) {
                    276:        case BOARD_NCR5380:
                    277:            flags = FLAG_NO_PSEUDO_DMA;
                    278:            break;
                    279:        case BOARD_NCR53C400:
                    280:            flags = FLAG_NCR53C400;
                    281:            break;
                    282:        }
                    283: 
                    284:        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
                    285:        instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
                    286: 
                    287:        NCR5380_init(instance, flags);
                    288: 
                    289:        if (overrides[current_override].irq != IRQ_AUTO)
                    290:            instance->irq = overrides[current_override].irq;
                    291:        else 
                    292:            instance->irq = NCR5380_probe_irq(instance, 0xffff);
                    293: 
                    294:        if (instance->irq != IRQ_NONE) 
                    295:            if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
                    296:                printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
                    297:                    instance->host_no, instance->irq);
                    298:                instance->irq = IRQ_NONE;
                    299:            } 
                    300: 
                    301:        if (instance->irq == IRQ_NONE) {
                    302:            printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
                    303:            printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
                    304:        }
                    305: 
                    306:        printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
                    307:        if (instance->irq == IRQ_NONE)
                    308:            printk (" interrupts disabled");
                    309:        else 
                    310:            printk (" irq %d", instance->irq);
                    311:        printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
                    312:            CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
                    313:        NCR5380_print_options(instance);
                    314:        printk("\n");
                    315: 
                    316:        ++current_override;
                    317:        ++count;
                    318:     }
                    319:     return count;
                    320: }
                    321: 
                    322: const char * generic_NCR5380_info (struct Scsi_Host* host) {
                    323:     static const char string[]="Generic NCR5380/53C400 Driver";
                    324:     return string;
                    325: }
                    326: 
                    327: int generic_NCR5380_release_resources(struct Scsi_Host * instance)
                    328: {
                    329:     NCR5380_local_declare();
                    330: 
                    331:     NCR5380_setup(instance);
                    332: 
                    333:     if (instance->irq != IRQ_NONE)
                    334:        free_irq(instance->irq, NULL);
                    335: 
                    336:        return 0;
                    337: }
                    338: 
                    339: #ifdef BIOSPARAM
                    340: /*
                    341:  * Function : int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
                    342:  *
                    343:  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
                    344:  *     the specified device / size.
                    345:  * 
                    346:  * Inputs : size = size of device in sectors (512 bytes), dev = block device
                    347:  *     major / minor, ip[] = {heads, sectors, cylinders}  
                    348:  *
                    349:  * Returns : always 0 (success), initializes ip
                    350:  *     
                    351:  */
                    352: 
                    353: /* 
                    354:  * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
                    355:  * using hard disks on a trantor should verify that this mapping corresponds
                    356:  * to that used by the BIOS / ASPI driver by running the linux fdisk program
                    357:  * and matching the H_C_S coordinates to what DOS uses.
                    358:  */
                    359: 
                    360: int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
                    361: {
                    362:   int size = disk->capacity;
                    363:   ip[0] = 64;
                    364:   ip[1] = 32;
                    365:   ip[2] = size >> 11;
                    366:   return 0;
                    367: }
                    368: #endif
                    369: 
                    370: #if NCR53C400_PSEUDO_DMA
                    371: static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,    int len)
                    372: {
                    373:     int blocks = len / 128;
                    374:     int start = 0;
                    375:     int i;
                    376:     int bl;
                    377:     NCR5380_local_declare();
                    378: 
                    379:     NCR5380_setup(instance);
                    380: 
                    381: #if (NDEBUG & NDEBUG_C400_PREAD)
                    382:     printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
                    383: #endif
                    384: 
                    385:     NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
                    386:     NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
                    387:     while (1) {
                    388:     
                    389: #if (NDEBUG & NDEBUG_C400_PREAD)
                    390:        printk("53C400r: %d blocks left\n", blocks);
                    391: #endif
                    392: 
                    393:        if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
                    394: #if (NDEBUG & NDEBUG_C400_PREAD)
                    395:            if (blocks)
                    396:                printk("53C400r: blocks still == %d\n", blocks);
                    397:            else
                    398:                printk("53C400r: Exiting loop\n");
                    399: #endif
                    400:            break;
                    401:        }
                    402: 
                    403: #if 1
                    404:        if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
                    405:            printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
                    406:            return -1;
                    407:        }
                    408: #endif
                    409: 
                    410: #if (NDEBUG & NDEBUG_C400_PREAD)
                    411:        printk("53C400r: Waiting for buffer, bl=%d\n", bl);
                    412: #endif
                    413: 
                    414:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
                    415:            ;
                    416: #if (NDEBUG & NDEBUG_C400_PREAD)
                    417:        printk("53C400r: Transferring 128 bytes\n");
                    418: #endif
                    419: 
                    420: #ifdef CONFIG_SCSI_G_NCR5380_PORT
                    421:        for (i=0; i<128; i++)
                    422:            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
                    423: #else
                    424:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
                    425:        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
                    426: #endif
                    427:        start+=128;
                    428:        blocks--;
                    429:     }
                    430: 
                    431:     if (blocks) {
                    432: #if (NDEBUG & NDEBUG_C400_PREAD)
                    433:        printk("53C400r: EXTRA: Waiting for buffer\n");
                    434: #endif
                    435:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
                    436:            ;
                    437: 
                    438: #if (NDEBUG & NDEBUG_C400_PREAD)
                    439:        printk("53C400r: Transferring EXTRA 128 bytes\n");
                    440: #endif
                    441: #ifdef CONFIG_SCSI_G_NCR5380_PORT
                    442:        for (i=0; i<128; i++)
                    443:            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
                    444: #else
                    445:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
                    446:        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
                    447: #endif
                    448:        start+=128;
                    449:        blocks--;
                    450:     }
                    451: #if (NDEBUG & NDEBUG_C400_PREAD)
                    452:     else
                    453:        printk("53C400r: No EXTRA required\n");
                    454: #endif
                    455: 
                    456: #if (NDEBUG & NDEBUG_C400_PREAD)
                    457:     printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
                    458: #endif
                    459: 
                    460:     if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
                    461:        printk("53C400r: no 53C80 gated irq after transfer");
                    462: #if (NDEBUG & NDEBUG_C400_PREAD)
                    463:     else
                    464:        printk("53C400r: Got 53C80 interrupt and tried to clear it\n");
                    465: #endif
                    466: 
                    467: /* DON'T DO THIS - THEY NEVER ARRIVE!
                    468:     printk("53C400r: Waiting for 53C80 registers\n");
                    469:     while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
                    470:        ;
                    471: */
                    472: 
                    473:     if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
                    474:        printk("53C400r: no end dma signal\n");
                    475: #if (NDEBUG & NDEBUG_C400_PREAD)
                    476:     else
                    477:        printk("53C400r: end dma as expected\n");
                    478: #endif
                    479: 
                    480:     NCR5380_write(MODE_REG, MR_BASE);
                    481:     NCR5380_read(RESET_PARITY_INTERRUPT_REG);
                    482:     return 0;
                    483: }
                    484:                
                    485: static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,    int len)
                    486: {
                    487:     int blocks = len / 128;
                    488:     int start = 0;
                    489:     int i;
                    490:     int bl;
                    491:     NCR5380_local_declare();
                    492: 
                    493:     NCR5380_setup(instance);
                    494: 
                    495: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    496:     printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
                    497: #endif
                    498: 
                    499:     NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
                    500:     NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
                    501:     while (1) {
                    502:        if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
                    503:            printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
                    504:            return -1;
                    505:        }
                    506: 
                    507:        if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
                    508: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    509:            if (blocks)
                    510:                printk("53C400w: exiting loop, blocks still == %d\n", blocks);
                    511:            else
                    512:                printk("53C400w: exiting loop\n");
                    513: #endif
                    514:            break;
                    515:        }
                    516: 
                    517: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    518:        printk("53C400w: %d blocks left\n", blocks);
                    519: 
                    520:        printk("53C400w: waiting for buffer, bl=%d\n", bl);
                    521: #endif
                    522:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
                    523:            ;
                    524: 
                    525: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    526:        printk("53C400w: transferring 128 bytes\n");
                    527: #endif
                    528: #ifdef CONFIG_SCSI_G_NCR5380_PORT
                    529:        for (i=0; i<128; i++)
                    530:            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
                    531: #else
                    532:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
                    533:        memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
                    534: #endif
                    535:        start+=128;
                    536:        blocks--;
                    537:     }
                    538:     if (blocks) {
                    539: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    540:        printk("53C400w: EXTRA waiting for buffer\n");
                    541: #endif
                    542:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
                    543:            ;
                    544: 
                    545: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    546:        printk("53C400w: transferring EXTRA 128 bytes\n");
                    547: #endif
                    548: #ifdef CONFIG_SCSI_G_NCR5380_PORT
                    549:        for (i=0; i<128; i++)
                    550:            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
                    551: #else
                    552:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
                    553:        memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
                    554: #endif
                    555:        start+=128;
                    556:        blocks--;
                    557:     }
                    558: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    559:     else
                    560:        printk("53C400w: No EXTRA required\n");
                    561: #endif
                    562:     
                    563: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    564:     printk("53C400w: Final values: blocks=%d   start=%d\n", blocks, start);
                    565: #endif
                    566: 
                    567: #if 0
                    568:     printk("53C400w: waiting for registers to be available\n");
                    569:     THEY NEVER DO!
                    570:     while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
                    571:        ;
                    572:     printk("53C400w: Got em\n");
                    573: #endif
                    574: 
                    575:     /* Let's wait for this instead - could be ugly */
                    576:     /* All documentation says to check for this. Maybe my hardware is too
                    577:      * fast. Waiting for it seems to work fine! KLL
                    578:      */
                    579:     while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
                    580:        ;
                    581: 
                    582:     /*
                    583:      * I know. i is certainly != 0 here but the loop is new. See previous
                    584:      * comment.
                    585:      */
                    586:     if (i) {
                    587: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    588:        printk("53C400w: got 53C80 gated irq (last block)\n");
                    589: #endif
                    590:        if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
                    591:            printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
                    592: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    593:        else
                    594:            printk("53C400w: Got END OF DMA\n");
                    595: #endif
                    596:     }
                    597:     else
                    598:        printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
                    599: 
                    600: #if 0
                    601:     if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
                    602:        printk("53C400w: no end dma signal\n");
                    603:     }
                    604: #endif
                    605: 
                    606: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    607:     printk("53C400w: waiting for last byte...\n");
                    608: #endif
                    609:     while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
                    610:        ;
                    611: 
                    612: #if (NDEBUG & NDEBUG_C400_PWRITE)
                    613:     printk("53C400w:     got last byte.\n");
                    614:     printk("53C400w: pwrite exiting with status 0, whoopee!\n");
                    615: #endif
                    616:     return 0;
                    617: }
                    618: #endif /* PSEUDO_DMA */
                    619: 
                    620: #include "NCR5380.c"
                    621: 
                    622: #define PRINTP(x) len += sprintf(buffer+len, x)
                    623: #define ANDP ,
                    624: 
                    625: static int sprint_opcode(char* buffer, int len, int opcode) {
                    626:     int start = len;
                    627:     PRINTP("0x%02x " ANDP opcode);
                    628:     return len-start;
                    629: }
                    630: 
                    631: static int sprint_command (char* buffer, int len, unsigned char *command) {
                    632:     int i,s,start=len;
                    633:     len += sprint_opcode(buffer, len, command[0]);
                    634:     for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
                    635:        PRINTP("%02x " ANDP command[i]);
                    636:     PRINTP("\n");
                    637:     return len-start;
                    638: }
                    639: 
                    640: static int sprint_Scsi_Cmnd (char* buffer, int len, Scsi_Cmnd *cmd) {
                    641:     int start = len;
                    642:     PRINTP("host number %d destination target %d, lun %d\n" ANDP
                    643:        cmd->host->host_no ANDP
                    644:        cmd->target ANDP
                    645:        cmd->lun);
                    646:     PRINTP("        command = ");
                    647:     len += sprint_command (buffer, len, cmd->cmnd);
                    648:     return len-start;
                    649: }
                    650: 
                    651: int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
                    652: {
                    653:     int len = 0;
                    654:     NCR5380_local_declare();
                    655:     unsigned char status;
                    656:     int i;
                    657:     struct Scsi_Host *scsi_ptr;
                    658:     Scsi_Cmnd *ptr;
                    659:     Scsi_Device *dev;
                    660:     struct NCR5380_hostdata *hostdata;
                    661: 
                    662:     cli();
                    663: 
                    664:     for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
                    665:        if (scsi_ptr->host_no == hostno)
                    666:            break;
                    667:     NCR5380_setup(scsi_ptr);
                    668:     hostdata = (struct NCR5380_hostdata *)scsi_ptr->hostdata;
                    669: 
                    670:     PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name);
                    671:     PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE);
                    672:     PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE);
                    673: #ifdef NCR53C400
                    674:     PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE);
                    675:     PRINTP("NCR53C400 card%s detected\n" ANDP  (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
                    676: # if NCR53C400_PSEUDO_DMA
                    677:     PRINTP("NCR53C400 pseudo DMA used\n");
                    678: # endif
                    679: #else
                    680:     PRINTP("NO NCR53C400 driver extensions\n");
                    681: #endif
                    682:     PRINTP("Using %s mapping at %s 0x%x, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
                    683:     if (scsi_ptr->irq == IRQ_NONE)
                    684:        PRINTP("no interrupt\n");
                    685:     else
                    686:        PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq);
                    687: 
                    688: #ifdef NCR5380_STATS
                    689:     if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue)
                    690:        PRINTP("There are commands pending, transfer rates may be crud\n");
                    691:     if (hostdata->pendingr)
                    692:        PRINTP("  %d pending reads" ANDP hostdata->pendingr);
                    693:     if (hostdata->pendingw)
                    694:        PRINTP("  %d pending writes" ANDP hostdata->pendingw);
                    695:     if (hostdata->pendingr || hostdata->pendingw)
                    696:        PRINTP("\n");
                    697:     for (dev = scsi_devices; dev; dev=dev->next) {
                    698:        if (dev->host == scsi_ptr) {
                    699:            unsigned long br = hostdata->bytes_read[dev->id];
                    700:            unsigned long bw = hostdata->bytes_write[dev->id];
                    701:            long tr = hostdata->time_read[dev->id] / HZ;
                    702:            long tw = hostdata->time_write[dev->id] / HZ;
                    703: 
                    704:            PRINTP("  T:%d %s " ANDP dev->id ANDP (dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int)dev->type] : "Unknown");
                    705:            for (i=0; i<8; i++)
                    706:                if (dev->vendor[i] >= 0x20)
                    707:                    *(buffer+(len++)) = dev->vendor[i];
                    708:            *(buffer+(len++)) = ' ';
                    709:            for (i=0; i<16; i++)
                    710:                if (dev->model[i] >= 0x20)
                    711:                    *(buffer+(len++)) = dev->model[i];
                    712:            *(buffer+(len++)) = ' ';
                    713:            for (i=0; i<4; i++)
                    714:                if (dev->rev[i] >= 0x20)
                    715:                    *(buffer+(len++)) = dev->rev[i];
                    716:            *(buffer+(len++)) = ' ';
                    717:                                    
                    718:            PRINTP("\n%10ld kb read    in %5ld secs" ANDP br/1024 ANDP tr);
                    719:            if (tr)
                    720:                PRINTP(" @ %5ld bps" ANDP br / tr); 
                    721: 
                    722:            PRINTP("\n%10ld kb written in %5ld secs" ANDP bw/1024 ANDP tw);
                    723:            if (tw)
                    724:                PRINTP(" @ %5ld bps" ANDP bw / tw); 
                    725:            PRINTP("\n");
                    726:        }
                    727:     }
                    728: #endif
                    729:        
                    730:     status = NCR5380_read(STATUS_REG);
                    731:     if (!(status & SR_REQ))
                    732:        PRINTP("REQ not asserted, phase unknown.\n");
                    733:     else {
                    734:        for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
                    735:                    (phases[i].value != (status & PHASE_MASK)); ++i)
                    736:            ;
                    737:        PRINTP("Phase %s\n" ANDP phases[i].name);
                    738:     }
                    739: 
                    740:     if (!hostdata->connected) {
                    741:        PRINTP("No currently connected command\n");
                    742:     } else {
                    743:        len += sprint_Scsi_Cmnd (buffer, len, (Scsi_Cmnd *) hostdata->connected);
                    744:     }
                    745: 
                    746:     PRINTP("issue_queue\n");
                    747: 
                    748:     for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
                    749:                ptr = (Scsi_Cmnd *) ptr->host_scribble)
                    750:        len += sprint_Scsi_Cmnd (buffer, len, ptr);
                    751: 
                    752:     PRINTP("disconnected_queue\n");
                    753: 
                    754:     for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
                    755:                ptr = (Scsi_Cmnd *) ptr->host_scribble)
                    756:        len += sprint_Scsi_Cmnd (buffer, len, ptr);
                    757:        
                    758:     *start = buffer + offset;
                    759:     len -= offset;
                    760:     if (len > length)
                    761:            len = length;
                    762:     sti();
                    763:     return len;
                    764: }
                    765: 
                    766: #undef PRINTP
                    767: #undef ANDP
                    768: 
                    769: #ifdef MODULE
                    770: /* Eventually this will go into an include file, but this will be later */
                    771: Scsi_Host_Template driver_template = GENERIC_NCR5380;
                    772: 
                    773: #include <linux/module.h>
                    774: #include "scsi_module.c"
                    775: #endif

unix.superglobalmegacorp.com

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