Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/t128.c, revision 1.1

1.1     ! root        1: #define AUTOSENSE
        !             2: #define PSEUDO_DMA
        !             3: 
        !             4: /*
        !             5:  * Trantor T128/T128F/T228 driver
        !             6:  *     Note : architecturally, the T100 and T130 are different and won't 
        !             7:  *     work
        !             8:  *
        !             9:  * Copyright 1993, Drew Eckhardt
        !            10:  *     Visionary Computing
        !            11:  *     (Unix and Linux consulting and custom programming)
        !            12:  *     [email protected]
        !            13:  *      +1 (303) 440-4894
        !            14:  *
        !            15:  * DISTRIBUTION RELEASE 3.
        !            16:  *
        !            17:  * For more information, please consult 
        !            18:  *
        !            19:  * Trantor Systems, Ltd.
        !            20:  * T128/T128F/T228 SCSI Host Adapter
        !            21:  * Hardware Specifications
        !            22:  * 
        !            23:  * Trantor Systems, Ltd. 
        !            24:  * 5415 Randall Place
        !            25:  * Fremont, CA 94538
        !            26:  * 1+ (415) 770-1400, FAX 1+ (415) 770-9910
        !            27:  * 
        !            28:  * and 
        !            29:  *
        !            30:  * NCR 5380 Family
        !            31:  * SCSI Protocol Controller
        !            32:  * Databook
        !            33:  *
        !            34:  * NCR Microelectronics
        !            35:  * 1635 Aeroplaza Drive
        !            36:  * Colorado Springs, CO 80916
        !            37:  * 1+ (719) 578-3400
        !            38:  * 1+ (800) 334-5454
        !            39:  */
        !            40: 
        !            41: /*
        !            42:  * Options : 
        !            43:  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
        !            44:  *      for commands that return with a CHECK CONDITION status. 
        !            45:  *
        !            46:  * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
        !            47:  * increase compared to polled I/O.
        !            48:  *
        !            49:  * PARITY - enable parity checking.  Not supported.
        !            50:  * 
        !            51:  * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
        !            52:  *
        !            53:  *
        !            54:  * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
        !            55:  *          only really want to use this if you're having a problem with
        !            56:  *          dropped characters during high speed communications, and even
        !            57:  *          then, you're going to be better off twiddling with transfersize.
        !            58:  *
        !            59:  * USLEEP - enable support for devices that don't disconnect.  Untested.
        !            60:  *
        !            61:  * The card is detected and initialized in one of several ways : 
        !            62:  * 1.  Autoprobe (default) - since the board is memory mapped, 
        !            63:  *     a BIOS signature is scanned for to locate the registers.
        !            64:  *     An interrupt is triggered to autoprobe for the interrupt
        !            65:  *     line.
        !            66:  *
        !            67:  * 2.  With command line overrides - t128=address,irq may be 
        !            68:  *     used on the LILO command line to override the defaults.
        !            69:  *
        !            70:  * 3.  With the T128_OVERRIDE compile time define.  This is 
        !            71:  *     specified as an array of address, irq tuples.  Ie, for
        !            72:  *     one board at the default 0xcc000 address, IRQ5, I could say 
        !            73:  *     -DT128_OVERRIDE={{0xcc000, 5}}
        !            74:  *     
        !            75:  *     Note that if the override methods are used, place holders must
        !            76:  *     be specified for other boards in the system.
        !            77:  * 
        !            78:  * T128/T128F jumper/dipswitch settings (note : on my sample, the switches 
        !            79:  * were epoxy'd shut, meaning I couldn't change the 0xcc000 base address) :
        !            80:  *
        !            81:  * T128    Sw7 Sw8 Sw6 = 0ws Sw5 = boot 
        !            82:  * T128F   Sw6 Sw7 Sw5 = 0ws Sw4 = boot Sw8 = floppy disable
        !            83:  * cc000   off off      
        !            84:  * c8000   off on
        !            85:  * dc000   on  off
        !            86:  * d8000   on  on
        !            87:  *
        !            88:  * 
        !            89:  * Interrupts 
        !            90:  * There is a 12 pin jumper block, jp1, numbered as follows : 
        !            91:  *   T128 (JP1)         T128F (J5)
        !            92:  * 2 4 6 8 10 12       11 9  7 5 3 1
        !            93:  * 1 3 5 7 9  11       12 10 8 6 4 2
        !            94:  *
        !            95:  * 3   2-4
        !            96:  * 5   1-3
        !            97:  * 7   3-5
        !            98:  * T128F only 
        !            99:  * 10 8-10
        !           100:  * 12 7-9
        !           101:  * 14 10-12
        !           102:  * 15 9-11
        !           103:  */
        !           104:  
        !           105: /*
        !           106:  * $Log: t128.c,v $
        !           107:  * Revision 1.1.1.1  1997/02/25 21:27:53  thomas
        !           108:  * Initial source
        !           109:  *
        !           110:  * Revision 1.1.1.1  1996/10/30 01:40:07  thomas
        !           111:  * Imported from UK22
        !           112:  *
        !           113:  * Revision 1.1  1996/03/25  20:25:52  goel
        !           114:  * Linux driver merge.
        !           115:  *
        !           116:  */
        !           117: 
        !           118: #include <asm/system.h>
        !           119: #include <linux/signal.h>
        !           120: #include <linux/sched.h>
        !           121: #include <asm/io.h>
        !           122: #include <linux/blk.h>
        !           123: #include "scsi.h"
        !           124: #include "hosts.h"
        !           125: #include "t128.h"
        !           126: #define AUTOPROBE_IRQ
        !           127: #include "NCR5380.h"
        !           128: #include "constants.h"
        !           129: #include "sd.h"
        !           130: #include<linux/stat.h>
        !           131: 
        !           132: struct proc_dir_entry proc_scsi_t128 = {
        !           133:     PROC_SCSI_T128, 4, "t128",
        !           134:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           135: };
        !           136: 
        !           137: 
        !           138: static struct override {
        !           139:     unsigned char *address;
        !           140:     int irq;
        !           141: } overrides 
        !           142: #ifdef T128_OVERRIDE
        !           143:     [] = T128_OVERRIDE;
        !           144: #else
        !           145:     [4] = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO},
        !           146:        {NULL,IRQ_AUTO}};
        !           147: #endif
        !           148: 
        !           149: #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
        !           150: 
        !           151: static struct base {
        !           152:     unsigned char *address;
        !           153:     int noauto;
        !           154: } bases[] = {{(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0},
        !           155:     {(unsigned char *) 0xdc000, 0}, {(unsigned char *) 0xd8000, 0}};
        !           156: 
        !           157: #define NO_BASES (sizeof (bases) / sizeof (struct base))
        !           158: 
        !           159: static const struct signature {
        !           160:     const char *string;
        !           161:     int offset;
        !           162: } signatures[] = {
        !           163: {"TSROM: SCSI BIOS, Version 1.12", 0x36},
        !           164: };
        !           165: 
        !           166: #define NO_SIGNATURES (sizeof (signatures) /  sizeof (struct signature))
        !           167: 
        !           168: /*
        !           169:  * Function : t128_setup(char *str, int *ints)
        !           170:  *
        !           171:  * Purpose : LILO command line initialization of the overrides array,
        !           172:  * 
        !           173:  * Inputs : str - unused, ints - array of integer parameters with ints[0]
        !           174:  *     equal to the number of ints.
        !           175:  *
        !           176:  */
        !           177: 
        !           178: void t128_setup(char *str, int *ints) {
        !           179:     static int commandline_current = 0;
        !           180:     int i;
        !           181:     if (ints[0] != 2) 
        !           182:        printk("t128_setup : usage t128=address,irq\n");
        !           183:     else 
        !           184:        if (commandline_current < NO_OVERRIDES) {
        !           185:            overrides[commandline_current].address = (unsigned char *) ints[1];
        !           186:            overrides[commandline_current].irq = ints[2];
        !           187:            for (i = 0; i < NO_BASES; ++i)
        !           188:                if (bases[i].address == (unsigned char *) ints[1]) {
        !           189:                    bases[i].noauto = 1;
        !           190:                    break;
        !           191:                }
        !           192:            ++commandline_current;
        !           193:        }
        !           194: }
        !           195: 
        !           196: /* 
        !           197:  * Function : int t128_detect(Scsi_Host_Template * tpnt)
        !           198:  *
        !           199:  * Purpose : detects and initializes T128,T128F, or T228 controllers
        !           200:  *     that were autoprobed, overridden on the LILO command line, 
        !           201:  *     or specified at compile time.
        !           202:  *
        !           203:  * Inputs : tpnt - template for this SCSI adapter.
        !           204:  * 
        !           205:  * Returns : 1 if a host adapter was found, 0 if not.
        !           206:  *
        !           207:  */
        !           208: 
        !           209: int t128_detect(Scsi_Host_Template * tpnt) {
        !           210:     static int current_override = 0, current_base = 0;
        !           211:     struct Scsi_Host *instance;
        !           212:     unsigned char *base;
        !           213:     int sig, count;
        !           214: 
        !           215:     tpnt->proc_dir = &proc_scsi_t128;
        !           216: 
        !           217:     for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
        !           218:        base = NULL;
        !           219: 
        !           220:        if (overrides[current_override].address)
        !           221:            base = overrides[current_override].address;
        !           222:        else 
        !           223:            for (; !base && (current_base < NO_BASES); ++current_base) {
        !           224: #if (TDEBUG & TDEBUG_INIT)
        !           225:     printk("scsi : probing address %08x\n", (unsigned int) bases[current_base].address);
        !           226: #endif
        !           227:                for (sig = 0; sig < NO_SIGNATURES; ++sig) 
        !           228:                    if (!bases[current_base].noauto && !memcmp 
        !           229:                        (bases[current_base].address + signatures[sig].offset, 
        !           230:                        signatures[sig].string, strlen(signatures[sig].string))) {
        !           231:                        base = bases[current_base].address;
        !           232: #if (TDEBUG & TDEBUG_INIT)
        !           233:                        printk("scsi-t128 : detected board.\n");
        !           234: #endif
        !           235:                        break;
        !           236:                    }
        !           237:            }
        !           238: 
        !           239: #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
        !           240:        printk("scsi-t128 : base = %08x\n", (unsigned int) base);
        !           241: #endif
        !           242: 
        !           243:        if (!base)
        !           244:            break;
        !           245: 
        !           246:        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
        !           247:        instance->base = base;
        !           248: 
        !           249:        NCR5380_init(instance, 0);
        !           250: 
        !           251:        if (overrides[current_override].irq != IRQ_AUTO)
        !           252:            instance->irq = overrides[current_override].irq;
        !           253:        else 
        !           254:            instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
        !           255: 
        !           256:        if (instance->irq != IRQ_NONE) 
        !           257:            if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128")) {
        !           258:                printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
        !           259:                    instance->host_no, instance->irq);
        !           260:                instance->irq = IRQ_NONE;
        !           261:            } 
        !           262: 
        !           263:        if (instance->irq == IRQ_NONE) {
        !           264:            printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
        !           265:            printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
        !           266:        }
        !           267: 
        !           268: #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
        !           269:        printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
        !           270: #endif
        !           271: 
        !           272:        printk("scsi%d : at 0x%08x", instance->host_no, (int) 
        !           273:            instance->base);
        !           274:        if (instance->irq == IRQ_NONE)
        !           275:            printk (" interrupts disabled");
        !           276:        else 
        !           277:            printk (" irq %d", instance->irq);
        !           278:        printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
        !           279:            CAN_QUEUE, CMD_PER_LUN, T128_PUBLIC_RELEASE);
        !           280:        NCR5380_print_options(instance);
        !           281:        printk("\n");
        !           282: 
        !           283:        ++current_override;
        !           284:        ++count;
        !           285:     }
        !           286:     return count;
        !           287: }
        !           288: 
        !           289: /*
        !           290:  * Function : int t128_biosparam(Disk * disk, kdev_t dev, int *ip)
        !           291:  *
        !           292:  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
        !           293:  *     the specified device / size.
        !           294:  * 
        !           295:  * Inputs : size = size of device in sectors (512 bytes), dev = block device
        !           296:  *     major / minor, ip[] = {heads, sectors, cylinders}  
        !           297:  *
        !           298:  * Returns : always 0 (success), initializes ip
        !           299:  *     
        !           300:  */
        !           301: 
        !           302: /* 
        !           303:  * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
        !           304:  * using hard disks on a trantor should verify that this mapping corresponds
        !           305:  * to that used by the BIOS / ASPI driver by running the linux fdisk program
        !           306:  * and matching the H_C_S coordinates to what DOS uses.
        !           307:  */
        !           308: 
        !           309: int t128_biosparam(Disk * disk, kdev_t dev, int * ip)
        !           310: {
        !           311:   int size = disk->capacity;
        !           312:   ip[0] = 64;
        !           313:   ip[1] = 32;
        !           314:   ip[2] = size >> 11;
        !           315:   return 0;
        !           316: }
        !           317: 
        !           318: /*
        !           319:  * Function : int NCR5380_pread (struct Scsi_Host *instance, 
        !           320:  *     unsigned char *dst, int len)
        !           321:  *
        !           322:  * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
        !           323:  *     dst
        !           324:  * 
        !           325:  * Inputs : dst = destination, len = length in bytes
        !           326:  *
        !           327:  * Returns : 0 on success, non zero on a failure such as a watchdog 
        !           328:  *     timeout.
        !           329:  */
        !           330: 
        !           331: static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
        !           332:     int len) {
        !           333:     register unsigned char *reg = (unsigned char *) (instance->base + 
        !           334:        T_DATA_REG_OFFSET), *d = dst;
        !           335:     register i = len;
        !           336: 
        !           337: 
        !           338: #if 0
        !           339:     for (; i; --i) {
        !           340:        while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           341: #else
        !           342:     while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           343:     for (; i; --i) {
        !           344: #endif
        !           345:        *d++ = *reg;
        !           346:     }
        !           347: 
        !           348:     if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
        !           349:        unsigned char tmp;
        !           350:        volatile unsigned char *foo;
        !           351:        foo = instance->base + T_CONTROL_REG_OFFSET;
        !           352:        tmp = *foo;
        !           353:        *foo = tmp | T_CR_CT;
        !           354:        *foo = tmp;
        !           355:        printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
        !           356:            instance->host_no);
        !           357:        return -1;
        !           358:     } else
        !           359:        return 0;
        !           360: }
        !           361: 
        !           362: /*
        !           363:  * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
        !           364:  *     unsigned char *src, int len)
        !           365:  *
        !           366:  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
        !           367:  *     src
        !           368:  * 
        !           369:  * Inputs : src = source, len = length in bytes
        !           370:  *
        !           371:  * Returns : 0 on success, non zero on a failure such as a watchdog 
        !           372:  *     timeout.
        !           373:  */
        !           374: 
        !           375: static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
        !           376:     int len) {
        !           377:     register unsigned char *reg = (unsigned char *) (instance->base + 
        !           378:        T_DATA_REG_OFFSET), *s = src;
        !           379:     register i = len;
        !           380: 
        !           381: #if 0
        !           382:     for (; i; --i) {
        !           383:        while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           384: #else
        !           385:     while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           386:     for (; i; --i) {
        !           387: #endif
        !           388:        *reg = *s++;
        !           389:     }
        !           390: 
        !           391:     if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
        !           392:        unsigned char tmp;
        !           393:        volatile unsigned char *foo;
        !           394:        foo = instance->base + T_CONTROL_REG_OFFSET;
        !           395:        tmp = *foo;
        !           396:        *foo = tmp | T_CR_CT;
        !           397:        *foo = tmp;
        !           398:        printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
        !           399:            instance->host_no);
        !           400:        return -1;
        !           401:     } else 
        !           402:        return 0;
        !           403: }
        !           404: 
        !           405: #ifdef MACH
        !           406: #include "NCR5380.src"
        !           407: #else
        !           408: #include "NCR5380.c"
        !           409: #endif
        !           410: 
        !           411: #ifdef MODULE
        !           412: /* Eventually this will go into an include file, but this will be later */
        !           413: Scsi_Host_Template driver_template = TRANTOR_T128;
        !           414: 
        !           415: #include "scsi_module.c"
        !           416: #endif

unix.superglobalmegacorp.com

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