Annotation of Gnu-Mach/linux/src/drivers/scsi/t128.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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