Annotation of Gnu-Mach/linux/src/drivers/scsi/aha1740.c, revision 1.1.1.3

1.1       root        1: /*  $Id: aha1740.c,v 1.1 1999/04/26 05:54:13 tb Exp $
                      2:  *  1993/03/31
                      3:  *  linux/kernel/aha1740.c
                      4:  *
                      5:  *  Based loosely on aha1542.c which is
                      6:  *  Copyright (C) 1992  Tommy Thorn and
                      7:  *  Modified by Eric Youngdale
                      8:  *
                      9:  *  This file is aha1740.c, written and
                     10:  *  Copyright (C) 1992,1993  Brad McLean
                     11:  *  
                     12:  *  Modifications to makecode and queuecommand
                     13:  *  for proper handling of multiple devices courteously
                     14:  *  provided by Michael Weller, March, 1993
                     15:  *
                     16:  *  Multiple adapter support, extended translation detection,
                     17:  *  update to current scsi subsystem changes, proc fs support,
                     18:  *  working (!) module support based on patches from Andreas Arens,
                     19:  *  by Andreas Degert <[email protected]>, 2/1997
                     20:  *
                     21:  * aha1740_makecode may still need even more work
                     22:  * if it doesn't work for your devices, take a look.
                     23:  */
                     24: 
                     25: #ifdef MODULE
                     26: #include <linux/module.h>
                     27: #endif
                     28: 
                     29: #include <linux/kernel.h>
                     30: #include <linux/head.h>
                     31: #include <linux/types.h>
                     32: #include <linux/string.h>
                     33: #include <linux/ioport.h>
                     34: #include <linux/proc_fs.h>
                     35: #include <linux/sched.h>
                     36: #include <asm/dma.h>
                     37: 
                     38: #include <asm/system.h>
                     39: #include <asm/io.h>
                     40: #include <linux/blk.h>
                     41: #include "scsi.h"
                     42: #include "hosts.h"
                     43: #include "sd.h"
                     44: 
                     45: #include "aha1740.h"
                     46: #include<linux/stat.h>
                     47: 
                     48: struct proc_dir_entry proc_scsi_aha1740 = {
                     49:     PROC_SCSI_AHA1740, 7, "aha1740",
                     50:     S_IFDIR | S_IRUGO | S_IXUGO, 2
                     51: };
                     52: 
                     53: /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
                     54:    IT WORK, THEN:
                     55: #define DEBUG
                     56: */
                     57: #ifdef DEBUG
                     58: #define DEB(x) x
                     59: #else
                     60: #define DEB(x)
                     61: #endif
                     62: 
                     63: /*
1.1.1.3 ! root       64: static const char RCSid[] = "$Header: cvs/gnumach/linux/src/drivers/scsi/Attic/aha1740.c,v 1.1 1999/04/26 05:54:13 tb Exp $";
1.1       root       65: */
                     66: 
                     67: struct aha1740_hostdata {
                     68:     unsigned int slot;
                     69:     unsigned int translation;
                     70:     unsigned int last_ecb_used;
                     71:     struct ecb ecb[AHA1740_ECBS];
                     72: };
                     73: 
                     74: #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
                     75: 
                     76: /* One for each IRQ level (9-15) */
                     77: static struct Scsi_Host * aha_host[8] = {NULL, };
                     78: 
                     79: int aha1740_proc_info(char *buffer, char **start, off_t offset,
                     80:                      int length, int hostno, int inout)
                     81: {
                     82:     int len;
                     83:     struct Scsi_Host * shpnt;
                     84:     struct aha1740_hostdata *host;
                     85: 
                     86:     if (inout)
                     87:        return(-ENOSYS);
                     88: 
                     89:     for (len = 0; len < 8; len++) {
                     90:        shpnt = aha_host[len];
                     91:        if (shpnt && shpnt->host_no == hostno)
                     92:            break;
                     93:     }
                     94:     host = HOSTDATA(shpnt);
                     95: 
                     96:     len = sprintf(buffer, "aha174x at IO:%x, IRQ %d, SLOT %d.\n"
                     97:                  "Extended translation %sabled.\n",
                     98:                  shpnt->io_port, shpnt->irq, host->slot,
                     99:                  host->translation ? "en" : "dis");
                    100: 
                    101:     if (offset > len) {
                    102:        *start = buffer;
                    103:        return 0;
                    104:     }
                    105: 
                    106:     *start = buffer + offset;
                    107:     len -= offset;
                    108:     if (len > length)
                    109:        len = length;
                    110:     return len;
                    111: }
                    112: 
                    113: 
                    114: int aha1740_makecode(unchar *sense, unchar *status)
                    115: {
                    116:     struct statusword
                    117:     {
                    118:        ushort  don:1,  /* Command Done - No Error */
                    119:                du:1,   /* Data underrun */
                    120:        :1,     qf:1,   /* Queue full */
                    121:                sc:1,   /* Specification Check */
                    122:                dor:1,  /* Data overrun */
                    123:                ch:1,   /* Chaining Halted */
                    124:                intr:1, /* Interrupt issued */
                    125:                asa:1,  /* Additional Status Available */
                    126:                sns:1,  /* Sense information Stored */
                    127:        :1,     ini:1,  /* Initialization Required */
                    128:                me:1,   /* Major error or exception */
                    129:        :1,     eca:1,  /* Extended Contingent alliance */
                    130:        :1;
                    131:     } status_word;
                    132:     int retval = DID_OK;
                    133: 
                    134:     status_word = * (struct statusword *) status;
                    135: #ifdef DEBUG
                    136:     printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",
                    137:           status[0], status[1], status[2], status[3],
                    138:           sense[0], sense[1], sense[2], sense[3]);
                    139: #endif
                    140:     if (!status_word.don) /* Anything abnormal was detected */
                    141:     {
                    142:        if ( (status[1]&0x18) || status_word.sc ) /*Additional info available*/
                    143:        {
                    144:            /* Use the supplied info for further diagnostics */
                    145:            switch ( status[2] )
                    146:            {
                    147:            case 0x12:
                    148:                if ( status_word.dor )
                    149:                    retval=DID_ERROR;   /* It's an Overrun */
                    150:                /* If not overrun, assume underrun and ignore it! */
                    151:            case 0x00: /* No info, assume no error, should not occur */
                    152:                break;
                    153:            case 0x11:
                    154:            case 0x21:
                    155:                retval=DID_TIME_OUT;
                    156:                break;
                    157:            case 0x0a:
                    158:                retval=DID_BAD_TARGET;
                    159:                break;
                    160:            case 0x04:
                    161:            case 0x05:
                    162:                retval=DID_ABORT;
                    163:                /* Either by this driver or the AHA1740 itself */
                    164:                break;
                    165:            default:
                    166:                retval=DID_ERROR; /* No further diagnostics possible */
                    167:            } 
                    168:        }
                    169:        else
                    170:        { /* Michael suggests, and Brad concurs: */
                    171:            if ( status_word.qf )
                    172:            {
                    173:                retval = DID_TIME_OUT; /* forces a redo */
                    174:                /* I think this specific one should not happen -Brad */
                    175:                printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
                    176:            }
                    177:            else if ( status[0]&0x60 )
                    178:            {
                    179:                retval = DID_ERROR; /* Didn't find a better error */
                    180:            }
                    181:            /* In any other case return DID_OK so for example
                    182:               CONDITION_CHECKS make it through to the appropriate
                    183:               device driver */
                    184:        }
                    185:     }
                    186:     /* Under all circumstances supply the target status -Michael */
                    187:     return status[3] | retval << 16;
                    188: }
                    189: 
                    190: int aha1740_test_port(unsigned int base)
                    191: {
                    192:     char name[4], tmp;
                    193: 
                    194:     /* Okay, look for the EISA ID's */
                    195:     name[0]= 'A' -1 + ((tmp = inb(HID0(base))) >> 2); /* First character */
                    196:     name[1]= 'A' -1 + ((tmp & 3) << 3);
                    197:     name[1]+= ((tmp = inb(HID1(base))) >> 5)&0x7;      /* Second Character */
                    198:     name[2]= 'A' -1 + (tmp & 0x1f);            /* Third Character */
                    199:     name[3]=0;
                    200:     tmp = inb(HID2(base));
                    201:     if ( strcmp ( name, HID_MFG ) || inb(HID2(base)) != HID_PRD )
                    202:        return 0;   /* Not an Adaptec 174x */
                    203: 
                    204: /*  if ( inb(HID3(base)) != HID_REV )
                    205:        printk("aha174x: Warning; board revision of %d; expected %d\n",
                    206:            inb(HID3(base)),HID_REV); */
                    207: 
                    208:     if ( inb(EBCNTRL(base)) != EBCNTRL_VALUE )
                    209:     {
                    210:        printk("aha174x: Board detected, but EBCNTRL = %x, so disabled it.\n",
                    211:            inb(EBCNTRL(base)));
                    212:        return 0;
                    213:     }
                    214: 
                    215:     if ( inb(PORTADR(base)) & PORTADDR_ENH )
                    216:        return 1;   /* Okay, we're all set */
                    217:        
                    218:     printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
                    219:     return 0;
                    220: }
                    221: 
                    222: /* A "high" level interrupt handler */
                    223: void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
                    224: {
                    225:     void (*my_done)(Scsi_Cmnd *);
                    226:     int errstatus, adapstat;
                    227:     int number_serviced;
                    228:     struct ecb *ecbptr;
                    229:     Scsi_Cmnd *SCtmp;
                    230:     unsigned int base;
                    231: 
                    232:     if (!aha_host[irq - 9])
                    233:        panic("aha1740.c: Irq from unknown host!\n");
                    234:     base = aha_host[irq - 9]->io_port;
                    235:     number_serviced = 0;
                    236: 
                    237:     while(inb(G2STAT(base)) & G2STAT_INTPEND)
                    238:     {
                    239:        DEB(printk("aha1740_intr top of loop.\n"));
                    240:        adapstat = inb(G2INTST(base));
                    241:        ecbptr = (struct ecb *) bus_to_virt(inl(MBOXIN0(base)));
                    242:        outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */
                    243:       
                    244:        switch ( adapstat & G2INTST_MASK )
                    245:        {
                    246:        case    G2INTST_CCBRETRY:
                    247:        case    G2INTST_CCBERROR:
                    248:        case    G2INTST_CCBGOOD:
                    249:            /* Host Ready -> Mailbox in complete */
                    250:            outb(G2CNTRL_HRDY,G2CNTRL(base));
                    251:            if (!ecbptr)
                    252:            {
                    253:                printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
                    254:                       inb(G2STAT(base)),adapstat,
                    255:                       inb(G2INTST(base)), number_serviced++);
                    256:                continue;
                    257:            }
                    258:            SCtmp = ecbptr->SCpnt;
                    259:            if (!SCtmp)
                    260:            {
                    261:                printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
                    262:                       inb(G2STAT(base)),adapstat,
                    263:                       inb(G2INTST(base)), number_serviced++);
                    264:                continue;
                    265:            }
                    266:            if (SCtmp->host_scribble)
                    267:                scsi_free(SCtmp->host_scribble, 512);
                    268:            /* Fetch the sense data, and tuck it away, in the required slot.
                    269:               The Adaptec automatically fetches it, and there is no
                    270:               guarantee that we will still have it in the cdb when we come
                    271:               back */
                    272:            if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR )
                    273:            {
                    274:                memcpy(SCtmp->sense_buffer, ecbptr->sense, 
                    275:                       sizeof(SCtmp->sense_buffer));
                    276:                errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
                    277:            }
                    278:            else
                    279:                errstatus = 0;
                    280:            DEB(if (errstatus) printk("aha1740_intr_handle: returning %6x\n",
                    281:                                      errstatus));
                    282:            SCtmp->result = errstatus;
                    283:            my_done = ecbptr->done;
                    284:            memset(ecbptr,0,sizeof(struct ecb)); 
                    285:            if ( my_done )
                    286:                my_done(SCtmp);
                    287:            break;
                    288:        case    G2INTST_HARDFAIL:
                    289:            printk(KERN_ALERT "aha1740 hardware failure!\n");
                    290:            panic("aha1740.c"); /* Goodbye */
                    291:        case    G2INTST_ASNEVENT:
                    292:            printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
                    293:                   adapstat, inb(MBOXIN0(base)), inb(MBOXIN1(base)),
                    294:                   inb(MBOXIN2(base)), inb(MBOXIN3(base))); /* Say What? */
                    295:            /* Host Ready -> Mailbox in complete */
                    296:            outb(G2CNTRL_HRDY,G2CNTRL(base));
                    297:            break;
                    298:        case    G2INTST_CMDGOOD:
                    299:            /* set immediate command success flag here: */
                    300:            break;
                    301:        case    G2INTST_CMDERROR:
                    302:            /* Set immediate command failure flag here: */
                    303:            break;
                    304:        }
                    305:        number_serviced++;
                    306:     }
                    307: }
                    308: 
                    309: int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
                    310: {
                    311:     unchar direction;
                    312:     unchar *cmd = (unchar *) SCpnt->cmnd;
                    313:     unchar target = SCpnt->target;
                    314:     struct aha1740_hostdata *host = HOSTDATA(SCpnt->host);
                    315:     unsigned long flags;
                    316:     void *buff = SCpnt->request_buffer;
                    317:     int bufflen = SCpnt->request_bufflen;
                    318:     int ecbno;
                    319:     DEB(int i);
                    320: 
                    321:     if(*cmd == REQUEST_SENSE)
                    322:     {
                    323:        if (bufflen != sizeof(SCpnt->sense_buffer))
                    324:        {
                    325:            printk("Wrong buffer length supplied for request sense (%d)\n",
                    326:                   bufflen);
                    327:        }
                    328:        SCpnt->result = 0;
                    329:        done(SCpnt); 
                    330:        return 0;
                    331:     }
                    332: 
                    333: #ifdef DEBUG
                    334:     if (*cmd == READ_10 || *cmd == WRITE_10)
                    335:        i = xscsi2int(cmd+2);
                    336:     else if (*cmd == READ_6 || *cmd == WRITE_6)
                    337:        i = scsi2int(cmd+2);
                    338:     else
                    339:        i = -1;
                    340:     printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
                    341:           target, *cmd, i, bufflen);
                    342:     printk("scsi cmd:");
                    343:     for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
                    344:     printk("\n");
                    345: #endif
                    346: 
                    347:     /* locate an available ecb */
                    348:     save_flags(flags);
                    349:     cli();
                    350:     ecbno = host->last_ecb_used + 1;           /* An optimization */
                    351:     if (ecbno >= AHA1740_ECBS)
                    352:        ecbno = 0;
                    353:     do {
                    354:        if (!host->ecb[ecbno].cmdw)
                    355:            break;
                    356:        ecbno++;
                    357:        if (ecbno >= AHA1740_ECBS)
                    358:            ecbno = 0;
                    359:     } while (ecbno != host->last_ecb_used);
                    360: 
                    361:     if (host->ecb[ecbno].cmdw)
                    362:        panic("Unable to find empty ecb for aha1740.\n");
                    363: 
                    364:     host->ecb[ecbno].cmdw = AHA1740CMD_INIT;   /* SCSI Initiator Command
                    365:                                                   doubles as reserved flag */
                    366: 
                    367:     host->last_ecb_used = ecbno;    
                    368:     restore_flags(flags);
                    369: 
                    370: #ifdef DEBUG
                    371:     printk("Sending command (%d %x)...", ecbno, done);
                    372: #endif
                    373: 
                    374:     host->ecb[ecbno].cdblen = SCpnt->cmd_len;  /* SCSI Command Descriptor Block Length */
                    375: 
                    376:     direction = 0;
                    377:     if (*cmd == READ_10 || *cmd == READ_6)
                    378:        direction = 1;
                    379:     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
                    380:        direction = 0;
                    381: 
                    382:     memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
                    383: 
                    384:     if (SCpnt->use_sg)
                    385:     {
                    386:        struct scatterlist * sgpnt;
                    387:        struct aha1740_chain * cptr;
                    388:        int i;
                    389:        DEB(unsigned char * ptr);
                    390: 
                    391:        host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command  w/scatter-gather*/
                    392:        SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
                    393:        sgpnt = (struct scatterlist *) SCpnt->request_buffer;
                    394:        cptr = (struct aha1740_chain *) SCpnt->host_scribble; 
                    395:        if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
                    396:        for(i=0; i<SCpnt->use_sg; i++)
                    397:        {
                    398:            cptr[i].datalen = sgpnt[i].length;
                    399:            cptr[i].dataptr = virt_to_bus(sgpnt[i].address);
                    400:        }
                    401:        host->ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
                    402:        host->ecb[ecbno].dataptr = virt_to_bus(cptr);
                    403: #ifdef DEBUG
                    404:        printk("cptr %x: ",cptr);
                    405:        ptr = (unsigned char *) cptr;
                    406:        for(i=0;i<24;i++) printk("%02x ", ptr[i]);
                    407: #endif
                    408:     }
                    409:     else
                    410:     {
                    411:        SCpnt->host_scribble = NULL;
                    412:        host->ecb[ecbno].datalen = bufflen;
                    413:        host->ecb[ecbno].dataptr = virt_to_bus(buff);
                    414:     }
                    415:     host->ecb[ecbno].lun = SCpnt->lun;
                    416:     host->ecb[ecbno].ses = 1;  /* Suppress underrun errors */
                    417:     host->ecb[ecbno].dir = direction;
                    418:     host->ecb[ecbno].ars = 1;  /* Yes, get the sense on an error */
                    419:     host->ecb[ecbno].senselen = 12;
                    420:     host->ecb[ecbno].senseptr = virt_to_bus(host->ecb[ecbno].sense);
                    421:     host->ecb[ecbno].statusptr = virt_to_bus(host->ecb[ecbno].status);
                    422:     host->ecb[ecbno].done = done;
                    423:     host->ecb[ecbno].SCpnt = SCpnt;
                    424: #ifdef DEBUG
                    425:     {
                    426:        int i;
                    427:        printk("aha1740_command: sending.. ");
                    428:        for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
                    429:            printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
                    430:     }
                    431:     printk("\n");
                    432: #endif
                    433:     if (done)
                    434:     { /*  The Adaptec Spec says the card is so fast that the loops will
                    435:          only be executed once in the code below. Even if this was true
                    436:          with the fastest processors when the spec was written, it doesn't
                    437:          seem to be true with todays fast processors. We print a warning
                    438:          if the code is executed more often than LOOPCNT_WARN. If this
                    439:          happens, it should be investigated. If the count reaches
                    440:          LOOPCNT_MAX, we assume something is broken; since there is no
                    441:          way to return an error (the return value is ignored by the
                    442:          mid-level scsi layer) we have to panic (and maybe that's the
                    443:          best thing we can do then anyhow). */
                    444: 
                    445: #define LOOPCNT_WARN 10                /* excessive mbxout wait -> syslog-msg */
                    446: #define LOOPCNT_MAX 1000000    /* mbxout deadlock -> panic() after ~ 2 sec. */
                    447:        int loopcnt;
                    448:        unsigned int base = SCpnt->host->io_port;
                    449:        DEB(printk("aha1740[%d] critical section\n",ecbno));
                    450:        save_flags(flags);
                    451:        cli();
                    452:        for (loopcnt = 0; ; loopcnt++) {
                    453:            if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
                    454:            if (loopcnt == LOOPCNT_WARN) {
                    455:                printk("aha1740[%d]_mbxout wait!\n",ecbno);
                    456:                cli(); /* printk may have done a sti()! */
                    457:            }
                    458:            if (loopcnt == LOOPCNT_MAX)
                    459:                panic("aha1740.c: mbxout busy!\n");
                    460:        }
                    461:        outl(virt_to_bus(host->ecb + ecbno), MBOXOUT0(base));
                    462:        for (loopcnt = 0; ; loopcnt++) {
                    463:            if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
                    464:            if (loopcnt == LOOPCNT_WARN) {
                    465:                printk("aha1740[%d]_attn wait!\n",ecbno);
                    466:                cli();
                    467:            }
                    468:            if (loopcnt == LOOPCNT_MAX)
                    469:                panic("aha1740.c: attn wait failed!\n");
                    470:        }
                    471:        outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
                    472:        restore_flags(flags);
                    473:        DEB(printk("aha1740[%d] request queued.\n",ecbno));
                    474:     }
                    475:     else
                    476:        printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
                    477:     return 0;
                    478: }
                    479: 
                    480: static void internal_done(Scsi_Cmnd * SCpnt)
                    481: {
                    482:     SCpnt->SCp.Status++;
                    483: }
                    484: 
                    485: int aha1740_command(Scsi_Cmnd * SCpnt)
                    486: {
                    487:     aha1740_queuecommand(SCpnt, internal_done);
                    488:     SCpnt->SCp.Status = 0;
                    489:     while (!SCpnt->SCp.Status)
                    490:        barrier();
                    491:     return SCpnt->result;
                    492: }
                    493: 
                    494: /* Query the board for its irq_level.  Nothing else matters
                    495:    in enhanced mode on an EISA bus. */
                    496: 
                    497: void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
                    498:                       unsigned int *translation)
                    499: {
                    500:     static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
                    501: 
                    502:     *irq_level = intab[inb(INTDEF(base)) & 0x7];
                    503:     *translation = inb(RESV1(base)) & 0x1;
                    504:     outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
                    505: }
                    506: 
                    507: int aha1740_detect(Scsi_Host_Template * tpnt)
                    508: {
                    509:     int count = 0, slot;
                    510: 
                    511:     DEB(printk("aha1740_detect: \n"));
                    512: 
                    513:     for ( slot=MINEISA; slot <= MAXEISA; slot++ )
                    514:     {
                    515:        int slotbase;
                    516:        unsigned int irq_level, translation;
                    517:        struct Scsi_Host *shpnt;
                    518:        struct aha1740_hostdata *host;
                    519:        slotbase = SLOTBASE(slot);
                    520:        /*
                    521:         * The ioports for eisa boards are generally beyond that used in the
                    522:         * check/allocate region code, but this may change at some point,
                    523:         * so we go through the motions.
                    524:         */
                    525:        if (check_region(slotbase, SLOTSIZE))  /* See if in use */
                    526:            continue;
                    527:        if (!aha1740_test_port(slotbase))
                    528:            continue;
                    529:        aha1740_getconfig(slotbase,&irq_level,&translation);
                    530:        if ((inb(G2STAT(slotbase)) &
                    531:             (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT)
                    532:        {       /* If the card isn't ready, hard reset it */
                    533:            outb(G2CNTRL_HRST, G2CNTRL(slotbase));
                    534:            outb(0, G2CNTRL(slotbase));
                    535:        }
                    536:        printk("Configuring aha174x at IO:%x, IRQ %d\n", slotbase, irq_level);
                    537:        printk("aha174x: Extended translation %sabled.\n",
                    538:               translation ? "en" : "dis");
                    539:        DEB(printk("aha1740_detect: enable interrupt channel %d\n",irq_level));
                    540:        if (request_irq(irq_level,aha1740_intr_handle,0,"aha1740",NULL)) {
                    541:            printk("Unable to allocate IRQ for adaptec controller.\n");
                    542:            continue;
                    543:        }
                    544:        shpnt = scsi_register(tpnt, sizeof(struct aha1740_hostdata));
                    545:        request_region(slotbase, SLOTSIZE, "aha1740");
                    546:        shpnt->base = 0;
                    547:        shpnt->io_port = slotbase;
                    548:        shpnt->n_io_port = SLOTSIZE;
                    549:        shpnt->irq = irq_level;
                    550:        shpnt->dma_channel = 0xff;
                    551:        host = HOSTDATA(shpnt);
                    552:        host->slot = slot;
                    553:        host->translation = translation;
                    554:        aha_host[irq_level - 9] = shpnt;
                    555:        count++;
                    556:     }
                    557:     return count;
                    558: }
                    559: 
                    560: /* Note:  They following two functions do not apply very well to the Adaptec,
                    561:    which basically manages its own affairs quite well without our interference,
                    562:    so I haven't put anything into them.  I can faintly imagine someone with a
                    563:    *very* badly behaved SCSI target (perhaps an old tape?) wanting the abort(),
                    564:    but it hasn't happened yet, and doing aborts brings the Adaptec to its
                    565:    knees.  I cannot (at this moment in time) think of any reason to reset the
                    566:    card once it's running.  So there. */
                    567: 
                    568: int aha1740_abort(Scsi_Cmnd * SCpnt)
                    569: {
                    570:     DEB(printk("aha1740_abort called\n"));
                    571:     return SCSI_ABORT_SNOOZE;
                    572: }
                    573: 
                    574: /* We do not implement a reset function here, but the upper level code assumes
                    575:    that it will get some kind of response for the command in SCpnt.  We must
                    576:    oblige, or the command will hang the scsi system */
                    577: 
                    578: int aha1740_reset(Scsi_Cmnd * SCpnt, unsigned int ignored)
                    579: {
                    580:     DEB(printk("aha1740_reset called\n"));
                    581:     return SCSI_RESET_PUNT;
                    582: }
                    583: 
                    584: int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
                    585: {
                    586:     int size = disk->capacity;
                    587:     int extended = HOSTDATA(disk->device->host)->translation;
                    588: 
                    589:     DEB(printk("aha1740_biosparam\n"));
                    590:     if (extended && (ip[2] > 1024))
                    591:     {
                    592:        ip[0] = 255;
                    593:        ip[1] = 63;
                    594:        ip[2] = size / (255 * 63);
                    595:     }
                    596:     else
                    597:     {
                    598:        ip[0] = 64;
                    599:        ip[1] = 32;
                    600:        ip[2] = size >> 11;
                    601:     }
                    602:     return 0;
                    603: }
                    604: 
                    605: #ifdef MODULE
                    606: /* Eventually this will go into an include file, but this will be later */
                    607: Scsi_Host_Template driver_template = AHA1740;
                    608: 
                    609: #include "scsi_module.c"
                    610: #endif
                    611: 
                    612: /* Okay, you made it all the way through.  As of this writing, 3/31/93, I'm
                    613: [email protected] or [email protected].  I'll try to help as time
                    614: permits if you have any trouble with this driver.  Happy Linuxing! */

unix.superglobalmegacorp.com

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