Annotation of Gnu-Mach/linux/src/drivers/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  1999/04/26 05:55:08  tb
        !           108:  * 1998-11-30  OKUJI Yoshinori  <[email protected]>
        !           109:  *
        !           110:  *     Clean up linux emulation code to make it architecture-independent
        !           111:  *     as much as possible.
        !           112:  *
        !           113:  *     * linux: Renamed from linuxdev.
        !           114:  *     * Makefile.in (objfiles): Add linux.o instead of linuxdev.o.
        !           115:  *     (MAKE): New variable. Used for the linux.o target.
        !           116:  *     * configure.in: Add AC_CHECK_TOOL(MAKE, make).
        !           117:  *     * i386/i386/spl.h: Include <i386/ipl.h>, for compatibility with
        !           118:  *     OSF Mach 3.0. Suggested by Elgin Lee <[email protected]>.
        !           119:  *     * linux/src: Renamed from linux/linux.
        !           120:  *     * linux/dev: Renamed from linux/mach.
        !           121:  *     * linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h,
        !           122:  *     instead of mach/include/linux/autoconf.h.
        !           123:  *     * Makefile.in (all): Target ../linux.o instead of ../linuxdev.o.
        !           124:  *     * linux/dev/drivers/block/genhd.c: Include <machine/spl.h> instead
        !           125:  *     of <i386/ipl.h>.
        !           126:  *     * linux/dev/drivers/net/auto_irq.c: Remove unneeded header files,
        !           127:  *     <i386/ipl.h> and <i386/pic.h>.
        !           128:  *     * linux/dev/init/main.c: Many i386-dependent codes moved to ...
        !           129:  *     * linux/dev/arch/i386/irq.c: ... here.
        !           130:  *     * linux/dev/arch/i386/setup.c: New file.
        !           131:  *     * linux/dev/arch/i386/linux_emul.h: Likewise.
        !           132:  *     * linux/dev/arch/i386/glue/timer.c: Merged into sched.c.
        !           133:  *     * linux/dev/arch/i386/glue/sched.c: Include <machine/spl.h> instead
        !           134:  *     of <i386/ipl.h>, and moved to ...
        !           135:  *     * linux/dev/kernel/sched.c: ... here.
        !           136:  *     * linux/dev/arch/i386/glue/block.c: Include <machine/spl.h> and
        !           137:  *     <linux_emul.h>, instead of i386-dependent header files, and
        !           138:  *     moved to ...
        !           139:  *     * linux/dev/glue/blocl.c: ... here.
        !           140:  *     * linux/dev/arch/i386/glue/net.c: Include <machine/spl.h> and
        !           141:  *     <linux_emul.h>, instead of i386-dependent header files, and
        !           142:  *     moved to ...
        !           143:  *     * linux/dev/glue/net.c: ... here.
        !           144:  *     * linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ...
        !           145:  *     * linux/dev/glue/misc.c: ... here.
        !           146:  *     * linux/dev/arch/i386/glue/kmem.c: Moved to ...
        !           147:  *     * linux/dev/glue/kmem.c: ... here.
        !           148:  *
        !           149:  */
        !           150: 
        !           151: #include <asm/system.h>
        !           152: #include <linux/signal.h>
        !           153: #include <linux/sched.h>
        !           154: #include <asm/io.h>
        !           155: #include <linux/blk.h>
        !           156: #include "scsi.h"
        !           157: #include "hosts.h"
        !           158: #include "t128.h"
        !           159: #define AUTOPROBE_IRQ
        !           160: #include "NCR5380.h"
        !           161: #include "constants.h"
        !           162: #include "sd.h"
        !           163: #include<linux/stat.h>
        !           164: 
        !           165: struct proc_dir_entry proc_scsi_t128 = {
        !           166:     PROC_SCSI_T128, 4, "t128",
        !           167:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           168: };
        !           169: 
        !           170: 
        !           171: static struct override {
        !           172:     unsigned char *address;
        !           173:     int irq;
        !           174: } overrides 
        !           175: #ifdef T128_OVERRIDE
        !           176:     [] = T128_OVERRIDE;
        !           177: #else
        !           178:     [4] = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO},
        !           179:        {NULL,IRQ_AUTO}};
        !           180: #endif
        !           181: 
        !           182: #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
        !           183: 
        !           184: static struct base {
        !           185:     unsigned char *address;
        !           186:     int noauto;
        !           187: } bases[] = {{(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0},
        !           188:     {(unsigned char *) 0xdc000, 0}, {(unsigned char *) 0xd8000, 0}};
        !           189: 
        !           190: #define NO_BASES (sizeof (bases) / sizeof (struct base))
        !           191: 
        !           192: static const struct signature {
        !           193:     const char *string;
        !           194:     int offset;
        !           195: } signatures[] = {
        !           196: {"TSROM: SCSI BIOS, Version 1.12", 0x36},
        !           197: };
        !           198: 
        !           199: #define NO_SIGNATURES (sizeof (signatures) /  sizeof (struct signature))
        !           200: 
        !           201: /*
        !           202:  * Function : t128_setup(char *str, int *ints)
        !           203:  *
        !           204:  * Purpose : LILO command line initialization of the overrides array,
        !           205:  * 
        !           206:  * Inputs : str - unused, ints - array of integer parameters with ints[0]
        !           207:  *     equal to the number of ints.
        !           208:  *
        !           209:  */
        !           210: 
        !           211: void t128_setup(char *str, int *ints) {
        !           212:     static int commandline_current = 0;
        !           213:     int i;
        !           214:     if (ints[0] != 2) 
        !           215:        printk("t128_setup : usage t128=address,irq\n");
        !           216:     else 
        !           217:        if (commandline_current < NO_OVERRIDES) {
        !           218:            overrides[commandline_current].address = (unsigned char *) ints[1];
        !           219:            overrides[commandline_current].irq = ints[2];
        !           220:            for (i = 0; i < NO_BASES; ++i)
        !           221:                if (bases[i].address == (unsigned char *) ints[1]) {
        !           222:                    bases[i].noauto = 1;
        !           223:                    break;
        !           224:                }
        !           225:            ++commandline_current;
        !           226:        }
        !           227: }
        !           228: 
        !           229: /* 
        !           230:  * Function : int t128_detect(Scsi_Host_Template * tpnt)
        !           231:  *
        !           232:  * Purpose : detects and initializes T128,T128F, or T228 controllers
        !           233:  *     that were autoprobed, overridden on the LILO command line, 
        !           234:  *     or specified at compile time.
        !           235:  *
        !           236:  * Inputs : tpnt - template for this SCSI adapter.
        !           237:  * 
        !           238:  * Returns : 1 if a host adapter was found, 0 if not.
        !           239:  *
        !           240:  */
        !           241: 
        !           242: int t128_detect(Scsi_Host_Template * tpnt) {
        !           243:     static int current_override = 0, current_base = 0;
        !           244:     struct Scsi_Host *instance;
        !           245:     unsigned char *base;
        !           246:     int sig, count;
        !           247: 
        !           248:     tpnt->proc_dir = &proc_scsi_t128;
        !           249:     tpnt->proc_info = &t128_proc_info;
        !           250: 
        !           251:     for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
        !           252:        base = NULL;
        !           253: 
        !           254:        if (overrides[current_override].address)
        !           255:            base = overrides[current_override].address;
        !           256:        else 
        !           257:            for (; !base && (current_base < NO_BASES); ++current_base) {
        !           258: #if (TDEBUG & TDEBUG_INIT)
        !           259:     printk("scsi : probing address %08x\n", (unsigned int) bases[current_base].address);
        !           260: #endif
        !           261:                for (sig = 0; sig < NO_SIGNATURES; ++sig) 
        !           262:                    if (!bases[current_base].noauto && !memcmp 
        !           263:                        (bases[current_base].address + signatures[sig].offset, 
        !           264:                        signatures[sig].string, strlen(signatures[sig].string))) {
        !           265:                        base = bases[current_base].address;
        !           266: #if (TDEBUG & TDEBUG_INIT)
        !           267:                        printk("scsi-t128 : detected board.\n");
        !           268: #endif
        !           269:                        break;
        !           270:                    }
        !           271:            }
        !           272: 
        !           273: #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
        !           274:        printk("scsi-t128 : base = %08x\n", (unsigned int) base);
        !           275: #endif
        !           276: 
        !           277:        if (!base)
        !           278:            break;
        !           279: 
        !           280:        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
        !           281:        instance->base = base;
        !           282: 
        !           283:        NCR5380_init(instance, 0);
        !           284: 
        !           285:        if (overrides[current_override].irq != IRQ_AUTO)
        !           286:            instance->irq = overrides[current_override].irq;
        !           287:        else 
        !           288:            instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
        !           289: 
        !           290:        if (instance->irq != IRQ_NONE) 
        !           291:            if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128", NULL)) {
        !           292:                printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
        !           293:                    instance->host_no, instance->irq);
        !           294:                instance->irq = IRQ_NONE;
        !           295:            } 
        !           296: 
        !           297:        if (instance->irq == IRQ_NONE) {
        !           298:            printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
        !           299:            printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
        !           300:        }
        !           301: 
        !           302: #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
        !           303:        printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
        !           304: #endif
        !           305: 
        !           306:        printk("scsi%d : at 0x%08x", instance->host_no, (int) 
        !           307:            instance->base);
        !           308:        if (instance->irq == IRQ_NONE)
        !           309:            printk (" interrupts disabled");
        !           310:        else 
        !           311:            printk (" irq %d", instance->irq);
        !           312:        printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
        !           313:            CAN_QUEUE, CMD_PER_LUN, T128_PUBLIC_RELEASE);
        !           314:        NCR5380_print_options(instance);
        !           315:        printk("\n");
        !           316: 
        !           317:        ++current_override;
        !           318:        ++count;
        !           319:     }
        !           320:     return count;
        !           321: }
        !           322: 
        !           323: /*
        !           324:  * Function : int t128_biosparam(Disk * disk, kdev_t dev, int *ip)
        !           325:  *
        !           326:  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
        !           327:  *     the specified device / size.
        !           328:  * 
        !           329:  * Inputs : size = size of device in sectors (512 bytes), dev = block device
        !           330:  *     major / minor, ip[] = {heads, sectors, cylinders}  
        !           331:  *
        !           332:  * Returns : always 0 (success), initializes ip
        !           333:  *     
        !           334:  */
        !           335: 
        !           336: /* 
        !           337:  * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
        !           338:  * using hard disks on a trantor should verify that this mapping corresponds
        !           339:  * to that used by the BIOS / ASPI driver by running the linux fdisk program
        !           340:  * and matching the H_C_S coordinates to what DOS uses.
        !           341:  */
        !           342: 
        !           343: int t128_biosparam(Disk * disk, kdev_t dev, int * ip)
        !           344: {
        !           345:   int size = disk->capacity;
        !           346:   ip[0] = 64;
        !           347:   ip[1] = 32;
        !           348:   ip[2] = size >> 11;
        !           349:   return 0;
        !           350: }
        !           351: 
        !           352: /*
        !           353:  * Function : int NCR5380_pread (struct Scsi_Host *instance, 
        !           354:  *     unsigned char *dst, int len)
        !           355:  *
        !           356:  * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
        !           357:  *     dst
        !           358:  * 
        !           359:  * Inputs : dst = destination, len = length in bytes
        !           360:  *
        !           361:  * Returns : 0 on success, non zero on a failure such as a watchdog 
        !           362:  *     timeout.
        !           363:  */
        !           364: 
        !           365: static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
        !           366:     int len) {
        !           367:     register unsigned char *reg = (unsigned char *) (instance->base + 
        !           368:        T_DATA_REG_OFFSET), *d = dst;
        !           369:     register int i = len;
        !           370: 
        !           371: 
        !           372: #if 0
        !           373:     for (; i; --i) {
        !           374:        while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           375: #else
        !           376:     while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           377:     for (; i; --i) {
        !           378: #endif
        !           379:        *d++ = *reg;
        !           380:     }
        !           381: 
        !           382:     if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
        !           383:        unsigned char tmp;
        !           384:        volatile unsigned char *foo;
        !           385:        foo = instance->base + T_CONTROL_REG_OFFSET;
        !           386:        tmp = *foo;
        !           387:        *foo = tmp | T_CR_CT;
        !           388:        *foo = tmp;
        !           389:        printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
        !           390:            instance->host_no);
        !           391:        return -1;
        !           392:     } else
        !           393:        return 0;
        !           394: }
        !           395: 
        !           396: /*
        !           397:  * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
        !           398:  *     unsigned char *src, int len)
        !           399:  *
        !           400:  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
        !           401:  *     src
        !           402:  * 
        !           403:  * Inputs : src = source, len = length in bytes
        !           404:  *
        !           405:  * Returns : 0 on success, non zero on a failure such as a watchdog 
        !           406:  *     timeout.
        !           407:  */
        !           408: 
        !           409: static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
        !           410:     int len) {
        !           411:     register unsigned char *reg = (unsigned char *) (instance->base + 
        !           412:        T_DATA_REG_OFFSET), *s = src;
        !           413:     register int i = len;
        !           414: 
        !           415: #if 0
        !           416:     for (; i; --i) {
        !           417:        while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           418: #else
        !           419:     while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
        !           420:     for (; i; --i) {
        !           421: #endif
        !           422:        *reg = *s++;
        !           423:     }
        !           424: 
        !           425:     if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
        !           426:        unsigned char tmp;
        !           427:        volatile unsigned char *foo;
        !           428:        foo = instance->base + T_CONTROL_REG_OFFSET;
        !           429:        tmp = *foo;
        !           430:        *foo = tmp | T_CR_CT;
        !           431:        *foo = tmp;
        !           432:        printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
        !           433:            instance->host_no);
        !           434:        return -1;
        !           435:     } else 
        !           436:        return 0;
        !           437: }
        !           438: 
        !           439: #include "NCR5380.c"
        !           440: 
        !           441: #ifdef MODULE
        !           442: /* Eventually this will go into an include file, but this will be later */
        !           443: Scsi_Host_Template driver_template = TRANTOR_T128;
        !           444: 
        !           445: #include "scsi_module.c"
        !           446: #endif

unix.superglobalmegacorp.com

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