Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/g_NCR5380.c, revision 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:  
        !            55: /*
        !            56:  * $Log: g_NCR5380.c,v $
        !            57:  * Revision 1.1.1.1  1997/02/25 21:27:49  thomas
        !            58:  * Initial source
        !            59:  *
        !            60:  * Revision 1.1.1.1  1996/10/30 01:40:05  thomas
        !            61:  * Imported from UK22
        !            62:  *
        !            63:  * Revision 1.1  1996/03/25  20:25:35  goel
        !            64:  * Linux driver merge.
        !            65:  *
        !            66:  */
        !            67: 
        !            68: #define AUTOPROBE_IRQ
        !            69: #define AUTOSENSE
        !            70: 
        !            71: #include <linux/config.h>
        !            72: 
        !            73: #ifdef MACH
        !            74: #define CONFIG_SCSI_G_NCR5380_MEM
        !            75: #endif
        !            76: 
        !            77: #ifdef CONFIG_SCSI_GENERIC_NCR53C400
        !            78: #define NCR53C400_PSEUDO_DMA 1
        !            79: #define PSEUDO_DMA
        !            80: #define NCR53C400
        !            81: #endif
        !            82: #if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM)
        !            83: #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)
        !            84: #endif
        !            85: #if !defined(CONFIG_SCSI_G_NCR5380_PORT) && !defined(CONFIG_SCSI_G_NCR5380_MEM)
        !            86: #error You must configure the Generic NCR 5380 SCSI Driver for one of memory mapped I/O and port mapped I/O.
        !            87: #endif
        !            88: 
        !            89: #include <asm/system.h>
        !            90: #include <asm/io.h>
        !            91: #include <linux/signal.h>
        !            92: #include <linux/sched.h>
        !            93: #include <linux/blk.h>
        !            94: #include "scsi.h"
        !            95: #include "hosts.h"
        !            96: #include "g_NCR5380.h"
        !            97: #include "NCR5380.h"
        !            98: #include "constants.h"
        !            99: #include "sd.h"
        !           100: #include<linux/stat.h>
        !           101: 
        !           102: struct proc_dir_entry proc_scsi_g_ncr5380 = {
        !           103:     PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380",
        !           104:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           105: };
        !           106: 
        !           107: static struct override {
        !           108:        NCR5380_implementation_fields;
        !           109:     int irq;
        !           110:     int dma;
        !           111:     int board; /* Use NCR53c400, Ricoh, etc. extensions ? */
        !           112: } overrides 
        !           113: #ifdef GENERIC_NCR5380_OVERRIDE 
        !           114:     [] = GENERIC_NCR5380_OVERRIDE
        !           115: #else
        !           116:     [1] = {{0,},};
        !           117: #endif
        !           118: 
        !           119: #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
        !           120: 
        !           121: /*
        !           122:  * Function : static internal_setup(int board, char *str, int *ints)
        !           123:  *
        !           124:  * Purpose : LILO command line initialization of the overrides array,
        !           125:  * 
        !           126:  * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board, 
        !           127:  *     or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints - 
        !           128:  *     array of integer parameters with ints[0] equal to the number of ints.
        !           129:  *
        !           130:  */
        !           131: 
        !           132: static void internal_setup(int board, char *str, int *ints) {
        !           133:     static int commandline_current = 0;
        !           134:     switch (board) {
        !           135:     case BOARD_NCR5380:
        !           136:        if (ints[0] != 2 && ints[0] != 3) 
        !           137:            printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
        !           138:        return;
        !           139:     case BOARD_NCR53C400:
        !           140:        if (ints[0] != 2)
        !           141:            printk("generic_NCR53C400_setup : usage ncr53c400= " STRVAL(NCR5380_map_name) ",irq\n");
        !           142:        return;
        !           143:     }
        !           144: 
        !           145:     if (commandline_current < NO_OVERRIDES) {
        !           146:        overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
        !           147:        overrides[commandline_current].irq = ints[2];
        !           148:        if (ints[0] == 3) 
        !           149:            overrides[commandline_current].dma = ints[3];
        !           150:        else 
        !           151:            overrides[commandline_current].dma = DMA_NONE;
        !           152:        overrides[commandline_current].board = board;
        !           153:            ++commandline_current;
        !           154:     }
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * Function : generic_NCR5380_setup (char *str, int *ints)
        !           159:  *
        !           160:  * Purpose : LILO command line initialization of the overrides array,
        !           161:  * 
        !           162:  * Inputs : str - unused, ints - array of integer paramters with ints[0] 
        !           163:  *     equal to the number of ints.
        !           164:  */
        !           165: 
        !           166: void generic_NCR5380_setup (char *str, int *ints) {
        !           167:     internal_setup (BOARD_NCR5380, str, ints);
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * Function : generic_NCR53C400_setup (char *str, int *ints)
        !           172:  *
        !           173:  * Purpose : LILO command line initialization of the overrides array,
        !           174:  * 
        !           175:  * Inputs : str - unused, ints - array of integer paramters with ints[0] 
        !           176:  *     equal to the number of ints.
        !           177:  */
        !           178: 
        !           179: void generic_NCR53C400_setup (char *str, int *ints) {
        !           180:     internal_setup (BOARD_NCR53C400, str, ints);
        !           181: }
        !           182: 
        !           183: /* 
        !           184:  * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
        !           185:  *
        !           186:  * Purpose : initializes generic NCR5380 driver based on the 
        !           187:  *     command line / compile time port and irq definitions.
        !           188:  *
        !           189:  * Inputs : tpnt - template for this SCSI adapter.
        !           190:  * 
        !           191:  * Returns : 1 if a host adapter was found, 0 if not.
        !           192:  *
        !           193:  */
        !           194: 
        !           195: int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
        !           196:     static int current_override = 0;
        !           197:     int count;
        !           198:     int flags = 0;
        !           199:     struct Scsi_Host *instance;
        !           200: 
        !           201:     tpnt->proc_dir = &proc_scsi_g_ncr5380;
        !           202: 
        !           203:     for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
        !           204:        if (!(overrides[current_override].NCR5380_map_name))
        !           205:            continue;
        !           206: 
        !           207:        switch (overrides[current_override].board) {
        !           208:        case BOARD_NCR5380:
        !           209:            flags = FLAG_NO_PSEUDO_DMA;
        !           210:            break;
        !           211:        case BOARD_NCR53C400:
        !           212:            flags = FLAG_NCR53C400;
        !           213:            break;
        !           214:        }
        !           215: 
        !           216:        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
        !           217:        instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
        !           218: 
        !           219:        NCR5380_init(instance, flags);
        !           220: 
        !           221:        if (overrides[current_override].irq != IRQ_AUTO)
        !           222:            instance->irq = overrides[current_override].irq;
        !           223:        else 
        !           224:            instance->irq = NCR5380_probe_irq(instance, 0xffff);
        !           225: 
        !           226:        if (instance->irq != IRQ_NONE) 
        !           227:            if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380")) {
        !           228:                printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
        !           229:                    instance->host_no, instance->irq);
        !           230:                instance->irq = IRQ_NONE;
        !           231:            } 
        !           232: 
        !           233:        if (instance->irq == IRQ_NONE) {
        !           234:            printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
        !           235:            printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
        !           236:        }
        !           237: 
        !           238:        printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
        !           239:        if (instance->irq == IRQ_NONE)
        !           240:            printk (" interrupts disabled");
        !           241:        else 
        !           242:            printk (" irq %d", instance->irq);
        !           243:        printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
        !           244:            CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
        !           245:        NCR5380_print_options(instance);
        !           246:        printk("\n");
        !           247: 
        !           248:        ++current_override;
        !           249:        ++count;
        !           250:     }
        !           251:     return count;
        !           252: }
        !           253: 
        !           254: const char * generic_NCR5380_info (void) {
        !           255:     static const char string[]="Generic NCR5380/53C400 Info";
        !           256:     return string;
        !           257: }
        !           258: 
        !           259: int generic_NCR5380_release_resources(struct Scsi_Host * instance)
        !           260: {
        !           261:     NCR5380_local_declare();
        !           262: 
        !           263:     NCR5380_setup(instance);
        !           264: 
        !           265:     free_irq(instance->irq);
        !           266: 
        !           267:        return 0;
        !           268: }
        !           269: 
        !           270: #ifdef BIOSPARAM
        !           271: /*
        !           272:  * Function : int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
        !           273:  *
        !           274:  * Purpose : Generates a BIOS / DOS compatable H-C-S mapping for 
        !           275:  *     the specified device / size.
        !           276:  * 
        !           277:  * Inputs : size = size of device in sectors (512 bytes), dev = block device
        !           278:  *     major / minor, ip[] = {heads, sectors, cylinders}  
        !           279:  *
        !           280:  * Returns : allways 0 (success), initializes ip
        !           281:  *     
        !           282:  */
        !           283: 
        !           284: /* 
        !           285:  * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
        !           286:  * using hard disks on a trantor should verify that this mapping corresponds
        !           287:  * to that used by the BIOS / ASPI driver by running the linux fdisk program
        !           288:  * and matching the H_C_S coordinates to what DOS uses.
        !           289:  */
        !           290: 
        !           291: int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
        !           292: {
        !           293:   int size = disk->capacity;
        !           294:   ip[0] = 64;
        !           295:   ip[1] = 32;
        !           296:   ip[2] = size >> 11;
        !           297:   return 0;
        !           298: }
        !           299: #endif
        !           300: 
        !           301: int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
        !           302: {
        !           303:        int len = 0;
        !           304:        struct Scsi_Host *scsi_ptr;
        !           305: 
        !           306:        for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
        !           307:                if (scsi_ptr->host_no == hostno)
        !           308:                        break;
        !           309: 
        !           310:        len += sprintf(buffer+len, "SCSI host number %d : %s\n", scsi_ptr->host_no,  scsi_ptr->hostt->name);
        !           311:        len += sprintf(buffer+len, "Generic NCR5380 driver version %d\n", GENERIC_NCR5380_PUBLIC_RELEASE);
        !           312:        len += sprintf(buffer+len, "NCR5380 driver core version %d\n", NCR5380_PUBLIC_RELEASE);
        !           313: #ifdef NCR53C400
        !           314:        len += sprintf(buffer+len, "NCR53C400 driver extension version %d\n", NCR53C400_PUBLIC_RELEASE);
        !           315:        len += sprintf(buffer+len, "NCR53C400 card%s detected\n",  (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
        !           316: # if NCR53C400_PSEUDO_DMA
        !           317:        len += sprintf(buffer+len, "NCR53C400 pseudo DMA being used\n");
        !           318: # endif
        !           319: #else
        !           320:        len += sprintf(buffer+len, "NO NCR53C400 driver extensions\n");
        !           321: #endif
        !           322:        len += sprintf(buffer+len, "Using %s mapping at %s 0x%x, ", STRVAL(NCR5380_map_config), STRVAL(NCR5380_map_name), scsi_ptr->NCR5380_instance_name);
        !           323:        if (scsi_ptr->irq == IRQ_NONE)
        !           324:                len += sprintf(buffer+len, "interrupts disabled\n");
        !           325:        else
        !           326:                len += sprintf(buffer+len, "on interrupt %d\n", scsi_ptr->irq);
        !           327: 
        !           328:        *start = buffer + offset;
        !           329:        len -= offset;
        !           330:        if (len > length)
        !           331:                len = length;
        !           332:        return len;
        !           333: }
        !           334: 
        !           335: #if NCR53C400_PSEUDO_DMA
        !           336: static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,    int len)
        !           337: {
        !           338:     int blocks = len / 128;
        !           339:     int start = 0;
        !           340:     int i;
        !           341:     int bl;
        !           342:     NCR5380_local_declare();
        !           343: 
        !           344:     NCR5380_setup(instance);
        !           345: 
        !           346: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           347:     printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
        !           348: #endif
        !           349: 
        !           350:     NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
        !           351:     NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
        !           352:     while (1) {
        !           353:     
        !           354: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           355:        printk("53C400r: %d blocks left\n", blocks);
        !           356: #endif
        !           357: 
        !           358:        if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
        !           359: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           360:            if (blocks)
        !           361:                printk("53C400r: blocks still == %d\n", blocks);
        !           362:            else
        !           363:                printk("53C400r: Exiting loop\n");
        !           364: #endif
        !           365:            break;
        !           366:        }
        !           367: 
        !           368: #if 1
        !           369:        if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
        !           370:            printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
        !           371:            return -1;
        !           372:        }
        !           373: #endif
        !           374: 
        !           375: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           376:        printk("53C400r: Waiting for buffer, bl=%d\n", bl);
        !           377: #endif
        !           378: 
        !           379:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
        !           380:            ;
        !           381: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           382:        printk("53C400r: Transferring 128 bytes\n");
        !           383: #endif
        !           384: 
        !           385: #ifdef CONFIG_SCSI_G_NCR5380_PORT
        !           386:        for (i=0; i<128; i++)
        !           387:            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
        !           388: #else
        !           389:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
        !           390:        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
        !           391: #endif
        !           392:        start+=128;
        !           393:        blocks--;
        !           394:     }
        !           395: 
        !           396: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           397:     printk("53C400r: EXTRA: Waiting for buffer\n");
        !           398: #endif
        !           399:     while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
        !           400:        ;
        !           401: 
        !           402: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           403:     printk("53C400r: Transferring EXTRA 128 bytes\n");
        !           404: #endif
        !           405: #ifdef CONFIG_SCSI_G_NCR5380_PORT
        !           406:        for (i=0; i<128; i++)
        !           407:            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
        !           408: #else
        !           409:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
        !           410:        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
        !           411: #endif
        !           412:     start+=128;
        !           413:     blocks--;
        !           414: 
        !           415: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           416:     printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
        !           417: #endif
        !           418: 
        !           419:     if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
        !           420:        printk("53C400r: no 53C80 gated irq after transfer");
        !           421: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           422:     else
        !           423:        printk("53C400r: Got 53C80 interupt and tried to clear it\n");
        !           424: #endif
        !           425: 
        !           426: /* DON'T DO THIS - THEY NEVER ARRIVE!
        !           427:     printk("53C400r: Waiting for 53C80 registers\n");
        !           428:     while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
        !           429:        ;
        !           430: */
        !           431: 
        !           432:     if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
        !           433:        printk("53C400r: no end dma signal\n");
        !           434: #if (NDEBUG & NDEBUG_C400_PREAD)
        !           435:     else
        !           436:        printk("53C400r: end dma as expected\n");
        !           437: #endif
        !           438: 
        !           439:     NCR5380_write(MODE_REG, MR_BASE);
        !           440:     NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !           441:     return 0;
        !           442: }
        !           443:                
        !           444: static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,    int len)
        !           445: {
        !           446:     int blocks = len / 128;
        !           447:     int start = 0;
        !           448:     int i;
        !           449:     int bl;
        !           450:     NCR5380_local_declare();
        !           451: 
        !           452:     NCR5380_setup(instance);
        !           453: 
        !           454: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           455:     printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
        !           456: #endif
        !           457: 
        !           458:     NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
        !           459:     NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
        !           460:     while (1) {
        !           461:        if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
        !           462:            printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
        !           463:            return -1;
        !           464:        }
        !           465: 
        !           466:        if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
        !           467: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           468:            if (blocks)
        !           469:                printk("53C400w: exiting loop, blocks still == %d\n", blocks);
        !           470:            else
        !           471:                printk("53C400w: exiting loop\n");
        !           472: #endif
        !           473:            break;
        !           474:        }
        !           475: 
        !           476: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           477:        printk("53C400w: %d blocks left\n", blocks);
        !           478: 
        !           479:        printk("53C400w: waiting for buffer, bl=%d\n", bl);
        !           480: #endif
        !           481:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
        !           482:            ;
        !           483: 
        !           484: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           485:        printk("53C400w: transferring 128 bytes\n");
        !           486: #endif
        !           487: #ifdef CONFIG_SCSI_G_NCR5380_PORT
        !           488:        for (i=0; i<128; i++)
        !           489:            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
        !           490: #else
        !           491:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
        !           492:        memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
        !           493: #endif
        !           494:        start+=128;
        !           495:        blocks--;
        !           496:     }
        !           497:     if (blocks) {
        !           498: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           499:        printk("53C400w: EXTRA waiting for buffer\n");
        !           500: #endif
        !           501:        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
        !           502:            ;
        !           503: 
        !           504: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           505:        printk("53C400w: transferring EXTRA 128 bytes\n");
        !           506: #endif
        !           507: #ifdef CONFIG_SCSI_G_NCR5380_PORT
        !           508:        for (i=0; i<128; i++)
        !           509:            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
        !           510: #else
        !           511:        /* implies CONFIG_SCSI_G_NCR5380_MEM */
        !           512:        memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
        !           513: #endif
        !           514:        start+=128;
        !           515:        blocks--;
        !           516:     }
        !           517: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           518:     else
        !           519:        printk("53C400w: No EXTRA required\n");
        !           520: #endif
        !           521:     
        !           522: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           523:     printk("53C400w: Final values: blocks=%d   start=%d\n", blocks, start);
        !           524: #endif
        !           525: 
        !           526: #if 0
        !           527:     printk("53C400w: waiting for registers to be available\n");
        !           528:     THEY NEVER DO!
        !           529:     while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
        !           530:        ;
        !           531:     printk("53C400w: Got em\n");
        !           532: #endif
        !           533: 
        !           534:     /* Let's wait for this instead - could be ugly */
        !           535:     /* All documentation says to check for this. Maybe my hardware is too
        !           536:      * fast. Waiting for it seems to work fine! KLL
        !           537:      */
        !           538:     while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
        !           539:        ;
        !           540: 
        !           541:     /*
        !           542:      * I know. i is certainly != 0 here but the loop is new. See previous
        !           543:      * comment.
        !           544:      */
        !           545:     if (i) {
        !           546: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           547:        prink("53C400w: got 53C80 gated irq (last block)\n");
        !           548: #endif
        !           549:        if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
        !           550:            printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
        !           551: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           552:        else
        !           553:            printk("53C400w: Got END OF DMA\n");
        !           554: #endif
        !           555:     }
        !           556:     else
        !           557:        printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
        !           558: 
        !           559: #if 0
        !           560:     if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
        !           561:        printk("53C400w: no end dma signal\n");
        !           562:     }
        !           563: #endif
        !           564: 
        !           565: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           566:     printk("53C400w: waiting for last byte...\n");
        !           567: #endif
        !           568:     while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
        !           569:        ;
        !           570: 
        !           571: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !           572:     printk("53C400w:     got last byte.\n");
        !           573:     printk("53C400w: pwrite exiting with status 0, whoopee!\n");
        !           574: #endif
        !           575:     return 0;
        !           576: }
        !           577: #endif /* PSEUDO_DMA */
        !           578: 
        !           579: #ifdef MACH
        !           580: #include "NCR5380.src"
        !           581: #else
        !           582: #include "NCR5380.c"
        !           583: #endif
        !           584: 
        !           585: #ifdef MODULE
        !           586: /* Eventually this will go into an include file, but this will be later */
        !           587: Scsi_Host_Template driver_template = GENERIC_NCR5380;
        !           588: 
        !           589: #include <linux/module.h>
        !           590: #include "scsi_module.c"
        !           591: #endif

unix.superglobalmegacorp.com

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