Annotation of Gnu-Mach/linux/src/drivers/scsi/aha1542.c, revision 1.1

1.1     ! root        1: /* $Id: aha1542.c,v 1.1 1999/04/26 05:54:11 tb Exp $
        !             2:  *  linux/kernel/aha1542.c
        !             3:  *
        !             4:  *  Copyright (C) 1992  Tommy Thorn
        !             5:  *  Copyright (C) 1993, 1994, 1995 Eric Youngdale
        !             6:  *
        !             7:  *  Modified by Eric Youngdale
        !             8:  *        Use request_irq and request_dma to help prevent unexpected conflicts
        !             9:  *        Set up on-board DMA controller, such that we do not have to
        !            10:  *        have the bios enabled to use the aha1542.
        !            11:  *  Modified by David Gentzel
        !            12:  *       Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus
        !            13:  *        controller).
        !            14:  *  Modified by Matti Aarnio
        !            15:  *        Accept parameters from LILO cmd-line. -- 1-Oct-94
        !            16:  *  Modified by Mike McLagan <[email protected]>
        !            17:  *        Recognise extended mode on AHA1542CP, different bit than 1542CF
        !            18:  *        1-Jan-97
        !            19:  *  Modified by Bjorn L. Thordarson and Einar Thor Einarsson
        !            20:  *        Recognize that DMA0 is valid DMA channel -- 13-Jul-98
        !            21:  */
        !            22: 
        !            23: #include <linux/module.h>
        !            24: 
        !            25: #include <linux/kernel.h>
        !            26: #include <linux/head.h>
        !            27: #include <linux/types.h>
        !            28: #include <linux/string.h>
        !            29: #include <linux/ioport.h>
        !            30: #include <linux/delay.h>
        !            31: #include <linux/sched.h>
        !            32: #include <linux/proc_fs.h>
        !            33: #include <asm/dma.h>
        !            34: #include <asm/system.h>
        !            35: #include <asm/io.h>
        !            36: #include <linux/blk.h>
        !            37: #include "scsi.h"
        !            38: #include "hosts.h"
        !            39: 
        !            40: 
        !            41: #include "aha1542.h"
        !            42: 
        !            43: #include<linux/stat.h>
        !            44: 
        !            45: struct proc_dir_entry proc_scsi_aha1542 = {
        !            46:     PROC_SCSI_AHA1542, 7, "aha1542",
        !            47:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !            48: };
        !            49: 
        !            50: #ifdef DEBUG
        !            51: #define DEB(x) x
        !            52: #else
        !            53: #define DEB(x)
        !            54: #endif
        !            55: /*
        !            56: static const char RCSid[] = "$Header: /afs/sipb.mit.edu/project/hurddev/cvsroot/gnumach/linux/src/drivers/scsi/aha1542.c,v 1.1 1999/04/26 05:54:11 tb Exp $";
        !            57: */
        !            58: 
        !            59: /* The adaptec can be configured for quite a number of addresses, but
        !            60: I generally do not want the card poking around at random.  We allow
        !            61: two addresses - this allows people to use the Adaptec with a Midi
        !            62: card, which also used 0x330 -- can be overridden with LILO! */
        !            63: 
        !            64: #define MAXBOARDS 2    /* Increase this and the sizes of the
        !            65:                           arrays below, if you need more.. */
        !            66: 
        !            67: static unsigned int bases[MAXBOARDS]={0x330, 0x334};
        !            68: 
        !            69: /* set by aha1542_setup according to the command line */
        !            70: static int setup_called[MAXBOARDS]   = {0,0};
        !            71: static int setup_buson[MAXBOARDS]    = {0,0};
        !            72: static int setup_busoff[MAXBOARDS]   = {0,0};
        !            73: static int setup_dmaspeed[MAXBOARDS] = {-1,-1};
        !            74: 
        !            75: static char *setup_str[MAXBOARDS] = {(char *)NULL,(char *)NULL};
        !            76: 
        !            77: /*
        !            78:  * LILO params:  aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]
        !            79:  *
        !            80:  * Where:  <PORTBASE> is any of the valid AHA addresses:
        !            81:  *                     0x130, 0x134, 0x230, 0x234, 0x330, 0x334
        !            82:  *        <BUSON>  is the time (in microsecs) that AHA spends on the AT-bus
        !            83:  *                 when transferring data.  1542A power-on default is 11us,
        !            84:  *                 valid values are in range: 2..15 (decimal)
        !            85:  *        <BUSOFF> is the time that AHA spends OFF THE BUS after while
        !            86:  *                 it is transferring data (not to monopolize the bus).
        !            87:  *                 Power-on default is 4us, valid range: 1..64 microseconds.
        !            88:  *        <DMASPEED> Default is jumper selected (1542A: on the J1),
        !            89:  *                 but experimenter can alter it with this.
        !            90:  *                 Valid values: 5, 6, 7, 8, 10 (MB/s)
        !            91:  *                 Factory default is 5 MB/s.
        !            92:  */
        !            93: 
        !            94: #define BIOS_TRANSLATION_1632 0  /* Used by some old 1542A boards */
        !            95: #define BIOS_TRANSLATION_6432 1 /* Default case these days */
        !            96: #define BIOS_TRANSLATION_25563 2 /* Big disk case */
        !            97: 
        !            98: struct aha1542_hostdata{
        !            99:        /* This will effectively start both of them at the first mailbox */
        !           100:        int bios_translation;   /* Mapping bios uses - for compatibility */
        !           101:        int aha1542_last_mbi_used;
        !           102:        int aha1542_last_mbo_used;
        !           103:        Scsi_Cmnd * SCint[AHA1542_MAILBOXES];
        !           104:        struct mailbox mb[2*AHA1542_MAILBOXES];
        !           105:        struct ccb ccb[AHA1542_MAILBOXES];
        !           106: };
        !           107: 
        !           108: #define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
        !           109: 
        !           110: static struct Scsi_Host * aha_host[7] = {NULL,};  /* One for each IRQ level (9-15) */
        !           111: 
        !           112: 
        !           113: 
        !           114: 
        !           115: #define WAITnexttimeout 3000000
        !           116: 
        !           117: static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt);
        !           118: static int aha1542_restart(struct Scsi_Host * shost);
        !           119: 
        !           120: #define aha1542_intr_reset(base)  outb(IRST, CONTROL(base))
        !           121: 
        !           122: #define WAIT(port, mask, allof, noneof)                                        \
        !           123:  { register WAITbits;                                                  \
        !           124:    register WAITtimeout = WAITnexttimeout;                             \
        !           125:    while (1) {                                                         \
        !           126:      WAITbits = inb(port) & (mask);                                    \
        !           127:      if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
        !           128:        break;                                                          \
        !           129:      if (--WAITtimeout == 0) goto fail;                                        \
        !           130:    }                                                                   \
        !           131:  }
        !           132: 
        !           133: /* Similar to WAIT, except we use the udelay call to regulate the
        !           134:    amount of time we wait.  */
        !           135: #define WAITd(port, mask, allof, noneof, timeout)                      \
        !           136:  { register WAITbits;                                                  \
        !           137:    register WAITtimeout = timeout;                                     \
        !           138:    while (1) {                                                         \
        !           139:      WAITbits = inb(port) & (mask);                                    \
        !           140:      if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
        !           141:        break;                                                          \
        !           142:      udelay(1000);                                                     \
        !           143:      if (--WAITtimeout == 0) goto fail;                                        \
        !           144:    }                                                                   \
        !           145:  }
        !           146: 
        !           147: static void aha1542_stat(void)
        !           148: {
        !           149: /*    int s = inb(STATUS), i = inb(INTRFLAGS);
        !           150:   printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); */
        !           151: }
        !           152: 
        !           153: /* This is a bit complicated, but we need to make sure that an interrupt
        !           154:    routine does not send something out while we are in the middle of this.
        !           155:    Fortunately, it is only at boot time that multi-byte messages
        !           156:    are ever sent. */
        !           157: static int aha1542_out(unsigned int base, unchar *cmdp, int len)
        !           158: {
        !           159:   unsigned long flags = 0;
        !           160:   
        !           161:   save_flags(flags);
        !           162:   if(len == 1) {
        !           163:     while(1==1){
        !           164:        WAIT(STATUS(base), CDF, 0, CDF);
        !           165:        cli();
        !           166:        if(inb(STATUS(base)) & CDF) {restore_flags(flags); continue;}
        !           167:        outb(*cmdp, DATA(base));
        !           168:        restore_flags(flags);
        !           169:        return 0;
        !           170:       }
        !           171:   } else {
        !           172:     cli();
        !           173:     while (len--)
        !           174:       {
        !           175:        WAIT(STATUS(base), CDF, 0, CDF);
        !           176:        outb(*cmdp++, DATA(base));
        !           177:       }
        !           178:     restore_flags(flags);
        !           179:   }
        !           180:     return 0;
        !           181:   fail:
        !           182:     restore_flags(flags);
        !           183:     printk("aha1542_out failed(%d): ", len+1); aha1542_stat();
        !           184:     return 1;
        !           185: }
        !           186: 
        !           187: /* Only used at boot time, so we do not need to worry about latency as much
        !           188:    here */
        !           189: static int aha1542_in(unsigned int base, unchar *cmdp, int len)
        !           190: {
        !           191:     unsigned long flags;
        !           192: 
        !           193:     save_flags(flags);
        !           194:     cli();
        !           195:     while (len--)
        !           196:       {
        !           197:          WAIT(STATUS(base), DF, DF, 0);
        !           198:          *cmdp++ = inb(DATA(base));
        !           199:       }
        !           200:     restore_flags(flags);
        !           201:     return 0;
        !           202:   fail:
        !           203:     restore_flags(flags);
        !           204:     printk("aha1542_in failed(%d): ", len+1); aha1542_stat();
        !           205:     return 1;
        !           206: }
        !           207: 
        !           208: /* Similar to aha1542_in, except that we wait a very short period of time.
        !           209:    We use this if we know the board is alive and awake, but we are not sure
        !           210:    if the board will respond to the command we are about to send or not */
        !           211: static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
        !           212: {
        !           213:     unsigned long flags;
        !           214:     
        !           215:     save_flags(flags);
        !           216:     cli();
        !           217:     while (len--)
        !           218:       {
        !           219:          WAITd(STATUS(base), DF, DF, 0, 100);
        !           220:          *cmdp++ = inb(DATA(base));
        !           221:       }
        !           222:     restore_flags(flags);
        !           223:     return 0;
        !           224:   fail:
        !           225:     restore_flags(flags);
        !           226:     return 1;
        !           227: }
        !           228: 
        !           229: static int makecode(unsigned hosterr, unsigned scsierr)
        !           230: {
        !           231:     switch (hosterr) {
        !           232:       case 0x0:
        !           233:       case 0xa: /* Linked command complete without error and linked normally */
        !           234:       case 0xb: /* Linked command complete without error, interrupt generated */
        !           235:        hosterr = 0;
        !           236:        break;
        !           237: 
        !           238:       case 0x11: /* Selection time out-The initiator selection or target
        !           239:                    reselection was not complete within the SCSI Time out period */
        !           240:        hosterr = DID_TIME_OUT;
        !           241:        break;
        !           242: 
        !           243:       case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
        !           244:                    than was allocated by the Data Length field or the sum of the
        !           245:                    Scatter / Gather Data Length fields. */
        !           246: 
        !           247:       case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
        !           248: 
        !           249:       case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was
        !           250:                    invalid. This usually indicates a software failure. */
        !           251: 
        !           252:       case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.
        !           253:                    This usually indicates a software failure. */
        !           254: 
        !           255:       case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set
        !           256:                    of linked CCB's does not specify the same logical unit number as
        !           257:                    the first. */
        !           258:       case 0x18: /* Invalid Target Direction received from Host-The direction of a
        !           259:                    Target Mode CCB was invalid. */
        !           260: 
        !           261:       case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
        !           262:                    received to service data transfer between the same target LUN
        !           263:                    and initiator SCSI ID in the same direction. */
        !           264: 
        !           265:       case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
        !           266:                    length segment or invalid segment list boundaries was received.
        !           267:                    A CCB parameter was invalid. */
        !           268:        DEB(printk("Aha1542: %x %x\n", hosterr, scsierr));
        !           269:        hosterr = DID_ERROR; /* Couldn't find any better */
        !           270:        break;
        !           271: 
        !           272:       case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
        !           273:                    phase sequence was requested by the target. The host adapter
        !           274:                    will generate a SCSI Reset Condition, notifying the host with
        !           275:                    a SCRD interrupt */
        !           276:        hosterr = DID_RESET;
        !           277:        break;
        !           278:       default:
        !           279:        printk("makecode: unknown hoststatus %x\n", hosterr);
        !           280:        break;
        !           281:     }
        !           282:     return scsierr|(hosterr << 16);
        !           283: }
        !           284: 
        !           285: static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
        !           286: {
        !           287:     int i;
        !           288:     unchar inquiry_cmd[] = {CMD_INQUIRY };
        !           289:     unchar inquiry_result[4];
        !           290:     unchar *cmdp;
        !           291:     int len;
        !           292:     volatile int debug = 0;
        !           293:     
        !           294:     /* Quick and dirty test for presence of the card. */
        !           295:     if(inb(STATUS(bse)) == 0xff) return 0;
        !           296: 
        !           297:     /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */
        !           298:     
        !           299:     /*  DEB(printk("aha1542_test_port called \n")); */
        !           300: 
        !           301:     /* In case some other card was probing here, reset interrupts */
        !           302:     aha1542_intr_reset(bse);     /* reset interrupts, so they don't block */   
        !           303: 
        !           304:     outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
        !           305: 
        !           306:     i = jiffies + 2;
        !           307:     while (i>jiffies); /* Wait a little bit for things to settle down. */
        !           308:     
        !           309:     debug = 1;
        !           310:     /* Expect INIT and IDLE, any of the others are bad */
        !           311:     WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
        !           312:     
        !           313:     debug = 2;
        !           314:     /* Shouldn't have generated any interrupts during reset */
        !           315:     if (inb(INTRFLAGS(bse))&INTRMASK) goto fail;
        !           316: 
        !           317: 
        !           318:     /* Perform a host adapter inquiry instead so we do not need to set
        !           319:        up the mailboxes ahead of time */
        !           320: 
        !           321:     aha1542_out(bse, inquiry_cmd, 1);
        !           322: 
        !           323:     debug = 3;
        !           324:     len = 4;
        !           325:     cmdp = &inquiry_result[0];
        !           326: 
        !           327:     while (len--)
        !           328:       {
        !           329:          WAIT(STATUS(bse), DF, DF, 0);
        !           330:          *cmdp++ = inb(DATA(bse));
        !           331:       }
        !           332:     
        !           333:     debug = 8;
        !           334:     /* Reading port should reset DF */
        !           335:     if (inb(STATUS(bse)) & DF) goto fail;
        !           336:     
        !           337:     debug = 9;
        !           338:     /* When HACC, command is completed, and we're though testing */
        !           339:     WAIT(INTRFLAGS(bse), HACC, HACC, 0);
        !           340:     /* now initialize adapter */
        !           341:     
        !           342:     debug = 10;
        !           343:     /* Clear interrupts */
        !           344:     outb(IRST, CONTROL(bse));
        !           345:     
        !           346:     debug = 11;
        !           347: 
        !           348:     return debug;                              /* 1 = ok */
        !           349:   fail:
        !           350:     return 0;                                  /* 0 = not ok */
        !           351: }
        !           352: 
        !           353: /* A "high" level interrupt handler */
        !           354: static void aha1542_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
        !           355: {
        !           356:     void (*my_done)(Scsi_Cmnd *) = NULL;
        !           357:     int errstatus, mbi, mbo, mbistatus;
        !           358:     int number_serviced;
        !           359:     unsigned int flags;
        !           360:     struct Scsi_Host * shost;
        !           361:     Scsi_Cmnd * SCtmp;
        !           362:     int flag;
        !           363:     int needs_restart;
        !           364:     struct mailbox * mb;
        !           365:     struct ccb  *ccb;
        !           366: 
        !           367:     shost = aha_host[irq - 9];
        !           368:     if(!shost) panic("Splunge!");
        !           369: 
        !           370:     mb = HOSTDATA(shost)->mb;
        !           371:     ccb = HOSTDATA(shost)->ccb;
        !           372: 
        !           373: #ifdef DEBUG
        !           374:     {
        !           375:     flag = inb(INTRFLAGS(shost->io_port));
        !           376:     printk("aha1542_intr_handle: ");
        !           377:     if (!(flag&ANYINTR)) printk("no interrupt?");
        !           378:     if (flag&MBIF) printk("MBIF ");
        !           379:     if (flag&MBOA) printk("MBOF ");
        !           380:     if (flag&HACC) printk("HACC ");
        !           381:     if (flag&SCRD) printk("SCRD ");
        !           382:     printk("status %02x\n", inb(STATUS(shost->io_port)));
        !           383:   };
        !           384: #endif
        !           385:     number_serviced = 0;
        !           386:     needs_restart = 0;
        !           387: 
        !           388:     while(1==1){
        !           389:       flag = inb(INTRFLAGS(shost->io_port));
        !           390: 
        !           391:       /* Check for unusual interrupts.  If any of these happen, we should
        !           392:         probably do something special, but for now just printing a message
        !           393:         is sufficient.  A SCSI reset detected is something that we really
        !           394:         need to deal with in some way. */
        !           395:       if (flag & ~MBIF) {
        !           396:        if (flag&MBOA) printk("MBOF ");
        !           397:        if (flag&HACC) printk("HACC ");
        !           398:        if (flag&SCRD) {
        !           399:          needs_restart = 1;
        !           400:          printk("SCRD ");
        !           401:        }
        !           402:       }
        !           403: 
        !           404:       aha1542_intr_reset(shost->io_port);
        !           405: 
        !           406:       save_flags(flags);
        !           407:       cli();
        !           408:       mbi = HOSTDATA(shost)->aha1542_last_mbi_used + 1;
        !           409:       if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
        !           410:       
        !           411:       do{
        !           412:        if(mb[mbi].status != 0) break;
        !           413:        mbi++;
        !           414:        if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
        !           415:       } while (mbi != HOSTDATA(shost)->aha1542_last_mbi_used);
        !           416:       
        !           417:       if(mb[mbi].status == 0){
        !           418:        restore_flags(flags);
        !           419:        /* Hmm, no mail.  Must have read it the last time around */
        !           420:        if (!number_serviced && !needs_restart)
        !           421:          printk("aha1542.c: interrupt received, but no mail.\n");
        !           422:        /* We detected a reset.  Restart all pending commands for
        !           423:           devices that use the hard reset option */
        !           424:        if(needs_restart) aha1542_restart(shost);
        !           425:        return;
        !           426:       };
        !           427: 
        !           428:       mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb);
        !           429:       mbistatus = mb[mbi].status;
        !           430:       mb[mbi].status = 0;
        !           431:       HOSTDATA(shost)->aha1542_last_mbi_used = mbi;
        !           432:       restore_flags(flags);
        !           433:       
        !           434: #ifdef DEBUG
        !           435:       {
        !           436:        if (ccb[mbo].tarstat|ccb[mbo].hastat)
        !           437:          printk("aha1542_command: returning %x (status %d)\n", 
        !           438:                 ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
        !           439:       };
        !           440: #endif
        !           441: 
        !           442:       if(mbistatus == 3) continue; /* Aborted command not found */
        !           443: 
        !           444: #ifdef DEBUG
        !           445:       printk("...done %d %d\n",mbo, mbi);
        !           446: #endif
        !           447:       
        !           448:       SCtmp = HOSTDATA(shost)->SCint[mbo];
        !           449: 
        !           450:       if (!SCtmp || !SCtmp->scsi_done) {
        !           451:        printk("aha1542_intr_handle: Unexpected interrupt\n");
        !           452:        printk("tarstat=%x, hastat=%x idlun=%x ccb#=%d \n", ccb[mbo].tarstat, 
        !           453:               ccb[mbo].hastat, ccb[mbo].idlun, mbo);
        !           454:        return;
        !           455:       }
        !           456:       
        !           457:       my_done = SCtmp->scsi_done;
        !           458:       if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
        !           459:       
        !           460:       /* Fetch the sense data, and tuck it away, in the required slot.  The
        !           461:         Adaptec automatically fetches it, and there is no guarantee that
        !           462:         we will still have it in the cdb when we come back */
        !           463:       if (ccb[mbo].tarstat == 2)
        !           464:        memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen], 
        !           465:               sizeof(SCtmp->sense_buffer));
        !           466:       
        !           467:       
        !           468:       /* is there mail :-) */
        !           469:       
        !           470:       /* more error checking left out here */
        !           471:       if (mbistatus != 1)
        !           472:        /* This is surely wrong, but I don't know what's right */
        !           473:        errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
        !           474:       else
        !           475:        errstatus = 0;
        !           476:       
        !           477: #ifdef DEBUG
        !           478:       if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus, 
        !           479:                           ccb[mbo].hastat, ccb[mbo].tarstat);
        !           480: #endif
        !           481: 
        !           482:       if (ccb[mbo].tarstat == 2) {
        !           483: #ifdef DEBUG
        !           484:        int i;
        !           485: #endif
        !           486:        DEB(printk("aha1542_intr_handle: sense:"));
        !           487: #ifdef DEBUG
        !           488:        for (i = 0; i < 12; i++)
        !           489:          printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]);
        !           490:        printk("\n");
        !           491: #endif
        !           492:        /*
        !           493:          DEB(printk("aha1542_intr_handle: buf:"));
        !           494:          for (i = 0; i < bufflen; i++)
        !           495:          printk("%02x ", ((unchar *)buff)[i]);
        !           496:          printk("\n");
        !           497:          */
        !           498:       }
        !           499:       DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
        !           500:       SCtmp->result = errstatus;
        !           501:       HOSTDATA(shost)->SCint[mbo] = NULL;  /* This effectively frees up the mailbox slot, as
        !           502:                             far as queuecommand is concerned */
        !           503:       my_done(SCtmp);
        !           504:       number_serviced++;
        !           505:     };
        !           506: }
        !           507: 
        !           508: int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        !           509: {
        !           510:     unchar ahacmd = CMD_START_SCSI;
        !           511:     unchar direction;
        !           512:     unchar *cmd = (unchar *) SCpnt->cmnd;
        !           513:     unchar target = SCpnt->target;
        !           514:     unchar lun = SCpnt->lun;
        !           515:     unsigned long flags;
        !           516:     void *buff = SCpnt->request_buffer;
        !           517:     int bufflen = SCpnt->request_bufflen;
        !           518:     int mbo;
        !           519:     struct mailbox * mb;
        !           520:     struct ccb  *ccb;
        !           521: 
        !           522:     DEB(int i);
        !           523: 
        !           524:     mb = HOSTDATA(SCpnt->host)->mb;
        !           525:     ccb = HOSTDATA(SCpnt->host)->ccb;
        !           526: 
        !           527:     DEB(if (target > 1) {
        !           528:       SCpnt->result = DID_TIME_OUT << 16;
        !           529:       done(SCpnt); return 0;});
        !           530:     
        !           531:     if(*cmd == REQUEST_SENSE){
        !           532: #ifndef DEBUG
        !           533:       if (bufflen != sizeof(SCpnt->sense_buffer)) {
        !           534:        printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
        !           535:       };
        !           536: #endif
        !           537:       SCpnt->result = 0;
        !           538:       done(SCpnt); 
        !           539:       return 0;
        !           540:     };
        !           541: 
        !           542: #ifdef DEBUG
        !           543:     if (*cmd == READ_10 || *cmd == WRITE_10)
        !           544:       i = xscsi2int(cmd+2);
        !           545:     else if (*cmd == READ_6 || *cmd == WRITE_6)
        !           546:       i = scsi2int(cmd+2);
        !           547:     else
        !           548:       i = -1;
        !           549:     if (done)
        !           550:       printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
        !           551:     else
        !           552:       printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
        !           553:     aha1542_stat();
        !           554:     printk("aha1542_queuecommand: dumping scsi cmd:");
        !           555:     for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
        !           556:     printk("\n");
        !           557:     if (*cmd == WRITE_10 || *cmd == WRITE_6)
        !           558:       return 0; /* we are still testing, so *don't* write */
        !           559: #endif
        !           560: /* Use the outgoing mailboxes in a round-robin fashion, because this
        !           561:    is how the host adapter will scan for them */
        !           562: 
        !           563:     save_flags(flags);
        !           564:     cli();
        !           565:     mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1;
        !           566:     if (mbo >= AHA1542_MAILBOXES) mbo = 0;
        !           567: 
        !           568:     do{
        !           569:       if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
        !           570:        break;
        !           571:       mbo++;
        !           572:       if (mbo >= AHA1542_MAILBOXES) mbo = 0;
        !           573:     } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used);
        !           574: 
        !           575:     if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo])
        !           576:       panic("Unable to find empty mailbox for aha1542.\n");
        !           577: 
        !           578:     HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt;  /* This will effectively prevent someone else from
        !           579:                            screwing with this cdb. */
        !           580: 
        !           581:     HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo;    
        !           582:     restore_flags(flags);
        !           583: 
        !           584: #ifdef DEBUG
        !           585:     printk("Sending command (%d %x)...",mbo, done);
        !           586: #endif
        !           587: 
        !           588:     any2scsi(mb[mbo].ccbptr, &ccb[mbo]); /* This gets trashed for some reason*/
        !           589: 
        !           590:     memset(&ccb[mbo], 0, sizeof(struct ccb));
        !           591: 
        !           592:     ccb[mbo].cdblen = SCpnt->cmd_len;
        !           593: 
        !           594:     direction = 0;
        !           595:     if (*cmd == READ_10 || *cmd == READ_6)
        !           596:        direction = 8;
        !           597:     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
        !           598:        direction = 16;
        !           599: 
        !           600:     memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
        !           601: 
        !           602:     if (SCpnt->use_sg) {
        !           603:       struct scatterlist * sgpnt;
        !           604:       struct chain * cptr;
        !           605: #ifdef DEBUG
        !           606:       unsigned char * ptr;
        !           607: #endif
        !           608:       int i;
        !           609:       ccb[mbo].op = 2;       /* SCSI Initiator Command  w/scatter-gather*/
        !           610:       SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
        !           611:       sgpnt = (struct scatterlist *) SCpnt->request_buffer;
        !           612:       cptr = (struct chain *) SCpnt->host_scribble; 
        !           613:       if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
        !           614:       for(i=0; i<SCpnt->use_sg; i++) {
        !           615:        if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 || 
        !           616:           (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
        !           617:          unsigned char * ptr;
        !           618:          printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
        !           619:          for(i=0;i<SCpnt->use_sg;i++){
        !           620:            printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
        !           621:                   sgpnt[i].length);
        !           622:          };
        !           623:          printk("cptr %x: ",(unsigned int) cptr);
        !           624:          ptr = (unsigned char *) &cptr[i];
        !           625:          for(i=0;i<18;i++) printk("%02x ", ptr[i]);
        !           626:          panic("Foooooooood fight!");
        !           627:        };
        !           628:        any2scsi(cptr[i].dataptr, sgpnt[i].address);
        !           629:        if(((unsigned  int) sgpnt[i].address) & 0xff000000) goto baddma;
        !           630:        any2scsi(cptr[i].datalen, sgpnt[i].length);
        !           631:       };
        !           632:       any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
        !           633:       any2scsi(ccb[mbo].dataptr, cptr);
        !           634: #ifdef DEBUG
        !           635:       printk("cptr %x: ",cptr);
        !           636:       ptr = (unsigned char *) cptr;
        !           637:       for(i=0;i<18;i++) printk("%02x ", ptr[i]);
        !           638: #endif
        !           639:     } else {
        !           640:       ccb[mbo].op = 0;       /* SCSI Initiator Command */
        !           641:       SCpnt->host_scribble = NULL;
        !           642:       any2scsi(ccb[mbo].datalen, bufflen);
        !           643:       if(((unsigned int) buff & 0xff000000)) goto baddma;
        !           644:       any2scsi(ccb[mbo].dataptr, buff);
        !           645:     };
        !           646:     ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/
        !           647:     ccb[mbo].rsalen = 16;
        !           648:     ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
        !           649:     ccb[mbo].commlinkid = 0;
        !           650: 
        !           651: #ifdef DEBUG
        !           652:     { int i;
        !           653:     printk("aha1542_command: sending.. ");
        !           654:     for (i = 0; i < sizeof(ccb[mbo])-10; i++)
        !           655:       printk("%02x ", ((unchar *)&ccb[mbo])[i]);
        !           656:     };
        !           657: #endif
        !           658:     
        !           659:     if (done) {
        !           660:        DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
        !           661:        SCpnt->scsi_done = done;
        !           662:        mb[mbo].status = 1;
        !           663:        aha1542_out(SCpnt->host->io_port, &ahacmd, 1);          /* start scsi command */
        !           664:        DEB(aha1542_stat());
        !           665:     }
        !           666:     else
        !           667:       printk("aha1542_queuecommand: done can't be NULL\n");
        !           668:     
        !           669:     return 0;
        !           670:  baddma:
        !           671:     panic("Buffer at address  > 16Mb used for 1542B");
        !           672: }
        !           673: 
        !           674: static void internal_done(Scsi_Cmnd * SCpnt)
        !           675: {
        !           676:        SCpnt->SCp.Status++;
        !           677: }
        !           678: 
        !           679: int aha1542_command(Scsi_Cmnd * SCpnt)
        !           680: {
        !           681:     DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
        !           682: 
        !           683:     aha1542_queuecommand(SCpnt, internal_done);
        !           684: 
        !           685:     SCpnt->SCp.Status = 0;
        !           686:     while (!SCpnt->SCp.Status)
        !           687:        barrier();
        !           688:     return SCpnt->result;
        !           689: }
        !           690: 
        !           691: /* Initialize mailboxes */
        !           692: static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
        !           693: {
        !           694:     int i;
        !           695:     struct mailbox * mb;
        !           696:     struct ccb  *ccb;
        !           697: 
        !           698:     unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
        !           699: 
        !           700:     mb = HOSTDATA(shpnt)->mb;
        !           701:     ccb = HOSTDATA(shpnt)->ccb;
        !           702: 
        !           703:     for(i=0; i<AHA1542_MAILBOXES; i++){
        !           704:       mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
        !           705:       any2scsi(mb[i].ccbptr, &ccb[i]);
        !           706:     };
        !           707:     aha1542_intr_reset(bse);     /* reset interrupts, so they don't block */   
        !           708:     any2scsi((cmd+2), mb);
        !           709:     aha1542_out(bse, cmd, 5);
        !           710:     WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0);
        !           711:     while (0) {
        !           712:       fail:
        !           713:        printk("aha1542_detect: failed setting up mailboxes\n");
        !           714:     }
        !           715:     aha1542_intr_reset(bse);
        !           716: }
        !           717: 
        !           718: static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan, unsigned char * scsi_id)
        !           719: {
        !           720:   unchar inquiry_cmd[] = {CMD_RETCONF };
        !           721:   unchar inquiry_result[3];
        !           722:   int i;
        !           723:   i = inb(STATUS(base_io));
        !           724:   if (i & DF) {
        !           725:     i = inb(DATA(base_io));
        !           726:   };
        !           727:   aha1542_out(base_io, inquiry_cmd, 1);
        !           728:   aha1542_in(base_io, inquiry_result, 3);
        !           729:   WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
        !           730:   while (0) {
        !           731:   fail:
        !           732:     printk("aha1542_detect: query board settings\n");
        !           733:   }
        !           734:   aha1542_intr_reset(base_io);
        !           735:   switch(inquiry_result[0]){
        !           736:   case 0x80:
        !           737:     *dma_chan = 7;
        !           738:     break;
        !           739:   case 0x40:
        !           740:     *dma_chan = 6;
        !           741:     break;
        !           742:   case 0x20:
        !           743:     *dma_chan = 5;
        !           744:     break;
        !           745:   case 0x01:
        !           746:     *dma_chan = 0;
        !           747:     break;
        !           748:   case 0:
        !           749:     /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
        !           750:        Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
        !           751:     *dma_chan = 0xFF;
        !           752:     break;
        !           753:   default:
        !           754:     printk("Unable to determine Adaptec DMA priority.  Disabling board\n");
        !           755:     return -1;
        !           756:   };
        !           757:   switch(inquiry_result[1]){
        !           758:   case 0x40:
        !           759:     *irq_level = 15;
        !           760:     break;
        !           761:   case 0x20:
        !           762:     *irq_level = 14;
        !           763:     break;
        !           764:   case 0x8:
        !           765:     *irq_level = 12;
        !           766:     break;
        !           767:   case 0x4:
        !           768:     *irq_level = 11;
        !           769:     break;
        !           770:   case 0x2:
        !           771:     *irq_level = 10;
        !           772:     break;
        !           773:   case 0x1:
        !           774:     *irq_level = 9;
        !           775:     break;
        !           776:   default:
        !           777:     printk("Unable to determine Adaptec IRQ level.  Disabling board\n");
        !           778:     return -1;
        !           779:   };
        !           780:   *scsi_id=inquiry_result[2] & 7;
        !           781:   return 0;
        !           782: }
        !           783: 
        !           784: /* This function should only be called for 1542C boards - we can detect
        !           785:    the special firmware settings and unlock the board */
        !           786: 
        !           787: static int aha1542_mbenable(int base)
        !           788: {
        !           789:   static unchar mbenable_cmd[3];
        !           790:   static unchar mbenable_result[2];
        !           791:   int retval;
        !           792:   
        !           793:   retval = BIOS_TRANSLATION_6432;
        !           794: 
        !           795:   mbenable_cmd[0]=CMD_EXTBIOS;
        !           796:   aha1542_out(base,mbenable_cmd,1);
        !           797:   if(aha1542_in1(base,mbenable_result,2))
        !           798:     return retval;
        !           799:   WAITd(INTRFLAGS(base),INTRMASK,HACC,0,100);
        !           800:   aha1542_intr_reset(base);
        !           801:   
        !           802:   if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
        !           803:      mbenable_cmd[0]=CMD_MBENABLE;
        !           804:      mbenable_cmd[1]=0;
        !           805:      mbenable_cmd[2]=mbenable_result[1];
        !           806: 
        !           807:      if((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03)) retval = BIOS_TRANSLATION_25563;
        !           808: 
        !           809:      aha1542_out(base,mbenable_cmd,3);
        !           810:      WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
        !           811:   };
        !           812:   while(0) {
        !           813: fail:
        !           814:     printk("aha1542_mbenable: Mailbox init failed\n");
        !           815:   }
        !           816: aha1542_intr_reset(base);
        !           817: return retval;
        !           818: }
        !           819: 
        !           820: /* Query the board to find out if it is a 1542 or a 1740, or whatever. */
        !           821: static int aha1542_query(int base_io, int * transl)
        !           822: {
        !           823:   unchar inquiry_cmd[] = {CMD_INQUIRY };
        !           824:   unchar inquiry_result[4];
        !           825:   int i;
        !           826:   i = inb(STATUS(base_io));
        !           827:   if (i & DF) {
        !           828:     i = inb(DATA(base_io));
        !           829:   };
        !           830:   aha1542_out(base_io, inquiry_cmd, 1);
        !           831:   aha1542_in(base_io, inquiry_result, 4);
        !           832:   WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
        !           833:   while (0) {
        !           834:   fail:
        !           835:     printk("aha1542_detect: query card type\n");
        !           836:   }
        !           837:   aha1542_intr_reset(base_io);
        !           838: 
        !           839:   *transl = BIOS_TRANSLATION_6432; /* Default case */
        !           840: 
        !           841: /* For an AHA1740 series board, we ignore the board since there is a
        !           842:    hardware bug which can lead to wrong blocks being returned if the board
        !           843:    is operating in the 1542 emulation mode.  Since there is an extended mode
        !           844:    driver, we simply ignore the board and let the 1740 driver pick it up.
        !           845: */
        !           846: 
        !           847:   if (inquiry_result[0] == 0x43) {
        !           848:     printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
        !           849:     return 1;
        !           850:   };
        !           851: 
        !           852:   /* Always call this - boards that do not support extended bios translation
        !           853:      will ignore the command, and we will set the proper default */
        !           854: 
        !           855:   *transl = aha1542_mbenable(base_io);
        !           856: 
        !           857:   return 0;
        !           858: }
        !           859: 
        !           860: /* called from init/main.c */
        !           861: void aha1542_setup( char *str, int *ints)
        !           862: {
        !           863:     const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";
        !           864:     static int setup_idx = 0;
        !           865:     int setup_portbase;
        !           866: 
        !           867:     if(setup_idx >= MAXBOARDS)
        !           868:       {
        !           869:        printk("aha1542: aha1542_setup called too many times! Bad LILO params ?\n");
        !           870:        printk("   Entryline 1: %s\n",setup_str[0]);
        !           871:        printk("   Entryline 2: %s\n",setup_str[1]);
        !           872:        printk("   This line:   %s\n",str);
        !           873:        return;
        !           874:       }
        !           875:     if (ints[0] < 1 || ints[0] > 4)
        !           876:       {
        !           877:        printk("aha1542: %s\n", str );
        !           878:        printk(ahausage);
        !           879:        printk("aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n");
        !           880:       }
        !           881: 
        !           882:     setup_called[setup_idx]=ints[0];
        !           883:     setup_str[setup_idx]=str;
        !           884: 
        !           885:     setup_portbase             = ints[0] >= 1 ? ints[1] : 0; /* Preserve the default value.. */
        !           886:     setup_buson   [setup_idx]  = ints[0] >= 2 ? ints[2] : 7;
        !           887:     setup_busoff  [setup_idx]  = ints[0] >= 3 ? ints[3] : 5;
        !           888:     if (ints[0] >= 4) {
        !           889:       int atbt = -1;
        !           890:       switch (ints[4]) {
        !           891:        case 5:
        !           892:            atbt = 0x00;
        !           893:            break;
        !           894:        case 6:
        !           895:            atbt = 0x04;
        !           896:            break;
        !           897:        case 7:
        !           898:            atbt = 0x01;
        !           899:            break;
        !           900:        case 8:
        !           901:            atbt = 0x02;
        !           902:            break;
        !           903:        case 10:
        !           904:            atbt = 0x03;
        !           905:            break;
        !           906:        default:
        !           907:            printk("aha1542: %s\n", str );
        !           908:            printk(ahausage);
        !           909:            printk("aha1542: Valid values for DMASPEED are 5-8, 10 MB/s.  Using jumper defaults.\n");
        !           910:            break;
        !           911:       }
        !           912:       setup_dmaspeed[setup_idx]  = atbt;
        !           913:     }
        !           914: 
        !           915:     if (setup_portbase != 0)
        !           916:       bases[setup_idx] = setup_portbase;
        !           917: 
        !           918:     ++setup_idx;
        !           919: }
        !           920: 
        !           921: /* return non-zero on detection */
        !           922: int aha1542_detect(Scsi_Host_Template * tpnt)
        !           923: {
        !           924:     unsigned char dma_chan;
        !           925:     unsigned char irq_level;
        !           926:     unsigned char scsi_id;
        !           927:     unsigned long flags;
        !           928:     unsigned int base_io;
        !           929:     int trans;
        !           930:     struct Scsi_Host * shpnt = NULL;
        !           931:     int count = 0;
        !           932:     int indx;
        !           933: 
        !           934:     DEB(printk("aha1542_detect: \n"));
        !           935: 
        !           936:     tpnt->proc_dir = &proc_scsi_aha1542;
        !           937: 
        !           938:     for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
        !           939:            if(bases[indx] != 0 && !check_region(bases[indx], 4)) { 
        !           940:                    shpnt = scsi_register(tpnt,
        !           941:                                          sizeof(struct aha1542_hostdata));
        !           942: 
        !           943:                    /* For now we do this - until kmalloc is more intelligent
        !           944:                       we are resigned to stupid hacks like this */
        !           945:                    if ((unsigned int) shpnt > 0xffffff) {
        !           946:                      printk("Invalid address for shpnt with 1542.\n");
        !           947:                      goto unregister;
        !           948:                    }
        !           949: 
        !           950:                    if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
        !           951: 
        !           952: 
        !           953:                    base_io = bases[indx];
        !           954:                    
        !           955:                    /* Set the Bus on/off-times as not to ruin floppy performance */
        !           956:            {
        !           957:                    unchar oncmd[] = {CMD_BUSON_TIME, 7};
        !           958:                    unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
        !           959: 
        !           960:                    if(setup_called[indx])
        !           961:                      {
        !           962:                        oncmd[1]  = setup_buson[indx];
        !           963:                        offcmd[1] = setup_busoff[indx];
        !           964:                      }
        !           965:                    
        !           966:                    aha1542_intr_reset(base_io);
        !           967:                    aha1542_out(base_io, oncmd, 2);
        !           968:                    WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
        !           969:                    aha1542_intr_reset(base_io);
        !           970:                    aha1542_out(base_io, offcmd, 2);
        !           971:                    WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
        !           972:                    if (setup_dmaspeed[indx] >= 0)
        !           973:                      {
        !           974:                        unchar dmacmd[] = {CMD_DMASPEED, 0};
        !           975:                        dmacmd[1] = setup_dmaspeed[indx];
        !           976:                        aha1542_intr_reset(base_io);
        !           977:                        aha1542_out(base_io, dmacmd, 2);
        !           978:                        WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
        !           979:                      }
        !           980:                    while (0) {
        !           981:                    fail:
        !           982:                            printk("aha1542_detect: setting bus on/off-time failed\n");
        !           983:                    }
        !           984:                    aha1542_intr_reset(base_io);
        !           985:            }
        !           986:                    if(aha1542_query(base_io, &trans))  goto unregister;
        !           987:                    
        !           988:                    if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1)  goto unregister;
        !           989:                    
        !           990:                    printk("Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level);
        !           991:                    if (dma_chan != 0xFF)
        !           992:                            printk(", DMA priority %d", dma_chan);
        !           993:                    printk("\n");
        !           994:                    
        !           995:                    DEB(aha1542_stat());
        !           996:                    setup_mailboxes(base_io, shpnt);
        !           997:                    
        !           998:                    DEB(aha1542_stat());
        !           999:                    
        !          1000:                    DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
        !          1001:                    save_flags(flags);
        !          1002:                    cli();
        !          1003:                    if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542", NULL)) {
        !          1004:                            printk("Unable to allocate IRQ for adaptec controller.\n");
        !          1005:                            restore_flags(flags);
        !          1006:                            goto unregister;
        !          1007:                    }
        !          1008:                    
        !          1009:                    if (dma_chan != 0xFF) {
        !          1010:                            if (request_dma(dma_chan,"aha1542")) {
        !          1011:                                    printk("Unable to allocate DMA channel for Adaptec.\n");
        !          1012:                                    free_irq(irq_level, NULL);
        !          1013:                                    restore_flags(flags);
        !          1014:                                    goto unregister;
        !          1015:                            }
        !          1016:                            
        !          1017:                            if (dma_chan == 0 || dma_chan >= 5) {
        !          1018:                                    set_dma_mode(dma_chan, DMA_MODE_CASCADE);
        !          1019:                                    enable_dma(dma_chan);
        !          1020:                            }
        !          1021:                    }
        !          1022:                    aha_host[irq_level - 9] = shpnt;
        !          1023:                    shpnt->this_id = scsi_id;
        !          1024:                    shpnt->unique_id = base_io;
        !          1025:                    shpnt->io_port = base_io;
        !          1026:                    shpnt->n_io_port = 4;  /* Number of bytes of I/O space used */
        !          1027:                    shpnt->dma_channel = dma_chan;
        !          1028:                    shpnt->irq = irq_level;
        !          1029:                    HOSTDATA(shpnt)->bios_translation  = trans;
        !          1030:                    if(trans == BIOS_TRANSLATION_25563) 
        !          1031:                      printk("aha1542.c: Using extended bios translation\n");
        !          1032:                    HOSTDATA(shpnt)->aha1542_last_mbi_used  = (2*AHA1542_MAILBOXES - 1);
        !          1033:                    HOSTDATA(shpnt)->aha1542_last_mbo_used  = (AHA1542_MAILBOXES - 1);
        !          1034:                    memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));
        !          1035:                    restore_flags(flags);
        !          1036: #if 0
        !          1037:                    DEB(printk(" *** READ CAPACITY ***\n"));
        !          1038:                    
        !          1039:            {
        !          1040:                    unchar buf[8];
        !          1041:                    static unchar cmd[] = {     READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        !          1042:                    int i;
        !          1043:                    
        !          1044:                    for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
        !          1045:                    for (i = 0; i < 2; ++i)
        !          1046:                            if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
        !          1047:                                    printk("aha_detect: LU %d sector_size %d device_size %d\n",
        !          1048:                                           i, xscsi2int(buf+4), xscsi2int(buf));
        !          1049:                            }
        !          1050:            }
        !          1051:                    
        !          1052:                    DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
        !          1053:                    
        !          1054:                    for (i = 0; i < 4; ++i)
        !          1055:                    {
        !          1056:                            unsigned char cmd[10];
        !          1057:                            static buffer[512];
        !          1058:                            
        !          1059:                            cmd[0] = READ_10;
        !          1060:                            cmd[1] = 0;
        !          1061:                            xany2scsi(cmd+2, i);
        !          1062:                            cmd[6] = 0;
        !          1063:                            cmd[7] = 0;
        !          1064:                            cmd[8] = 1;
        !          1065:                            cmd[9] = 0;
        !          1066:                            aha1542_command(0, cmd, buffer, 512);
        !          1067:                    }
        !          1068: #endif    
        !          1069:                    request_region(bases[indx], 4,"aha1542");  /* Register the IO ports that we use */
        !          1070:                    count++;
        !          1071:                    continue;
        !          1072:            unregister:
        !          1073:                    scsi_unregister(shpnt);
        !          1074:                    continue;
        !          1075:                    
        !          1076:            };
        !          1077:        
        !          1078:     return count;
        !          1079: }
        !          1080: 
        !          1081: static int aha1542_restart(struct Scsi_Host * shost)
        !          1082: {
        !          1083:   int i;
        !          1084:   int count = 0;
        !          1085: #if 0
        !          1086:   unchar ahacmd = CMD_START_SCSI;
        !          1087: #endif
        !          1088: 
        !          1089:   for(i=0; i< AHA1542_MAILBOXES; i++)
        !          1090:    if(HOSTDATA(shost)->SCint[i] && 
        !          1091:       !(HOSTDATA(shost)->SCint[i]->device->soft_reset))
        !          1092:      {
        !          1093: #if 0
        !          1094:        HOSTDATA(shost)->mb[i].status = 1; /* Indicate ready to restart... */
        !          1095: #endif
        !          1096:        count++;
        !          1097:      }     
        !          1098: 
        !          1099:   printk("Potential to restart %d stalled commands...\n", count);
        !          1100: #if 0
        !          1101:   /* start scsi command */
        !          1102:   if (count) aha1542_out(shost->io_port, &ahacmd, 1);
        !          1103: #endif
        !          1104:   return 0;
        !          1105: }
        !          1106: 
        !          1107: /* The abort command does not leave the device in a clean state where
        !          1108:    it is available to be used again.  Until this gets worked out, we will
        !          1109:    leave it commented out.  */
        !          1110: 
        !          1111: int aha1542_abort(Scsi_Cmnd * SCpnt)
        !          1112: {
        !          1113: #if 0
        !          1114:   unchar ahacmd = CMD_START_SCSI;
        !          1115:   unsigned long flags;
        !          1116:   struct mailbox * mb;
        !          1117:   int mbi, mbo, i;
        !          1118: 
        !          1119:   printk("In aha1542_abort: %x %x\n",
        !          1120:         inb(STATUS(SCpnt->host->io_port)),
        !          1121:         inb(INTRFLAGS(SCpnt->host->io_port)));
        !          1122: 
        !          1123:   save_flags(flags);
        !          1124:   cli();
        !          1125:   mb = HOSTDATA(SCpnt->host)->mb;
        !          1126:   mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1;
        !          1127:   if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
        !          1128:   
        !          1129:   do{
        !          1130:     if(mb[mbi].status != 0) break;
        !          1131:     mbi++;
        !          1132:     if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
        !          1133:   } while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used);
        !          1134:   restore_flags(flags);
        !          1135: 
        !          1136:   if(mb[mbi].status) {
        !          1137:     printk("Lost interrupt discovered on irq %d - attempting to recover\n", 
        !          1138:           SCpnt->host->irq);
        !          1139:     aha1542_intr_handle(SCpnt->host->irq, NULL);
        !          1140:     return 0;
        !          1141:   }
        !          1142: 
        !          1143:   /* OK, no lost interrupt.  Try looking to see how many pending commands
        !          1144:      we think we have. */
        !          1145: 
        !          1146:   for(i=0; i< AHA1542_MAILBOXES; i++)
        !          1147:    if(HOSTDATA(SCpnt->host)->SCint[i])
        !          1148:      {
        !          1149:        if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
        !          1150:         printk("Timed out command pending for %s\n",
        !          1151:                kdevname(SCpnt->request.rq_dev));
        !          1152:         if (HOSTDATA(SCpnt->host)->mb[i].status) {
        !          1153:           printk("OGMB still full - restarting\n");
        !          1154:           aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
        !          1155:         };
        !          1156:        } else
        !          1157:         printk("Other pending command %s\n",
        !          1158:                kdevname(SCpnt->request.rq_dev));
        !          1159:      }
        !          1160: 
        !          1161: #endif
        !          1162: 
        !          1163:     DEB(printk("aha1542_abort\n"));
        !          1164: #if 0
        !          1165:     save_flags(flags);
        !          1166:     cli();
        !          1167:     for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
        !          1168:       if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
        !          1169:        mb[mbo].status = 2;  /* Abort command */
        !          1170:        aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */
        !          1171:        restore_flags(flags);
        !          1172:        break;
        !          1173:       };
        !          1174: #endif
        !          1175:     return SCSI_ABORT_SNOOZE;
        !          1176: }
        !          1177: 
        !          1178: /* We do not implement a reset function here, but the upper level code
        !          1179:    assumes that it will get some kind of response for the command in
        !          1180:    SCpnt.  We must oblige, or the command will hang the scsi system.
        !          1181:    For a first go, we assume that the 1542 notifies us with all of the
        !          1182:    pending commands (it does implement soft reset, after all). */
        !          1183: 
        !          1184: int aha1542_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
        !          1185: {
        !          1186:     unchar ahacmd = CMD_START_SCSI;
        !          1187:     int i;
        !          1188: 
        !          1189:     /*
        !          1190:      * See if a bus reset was suggested.
        !          1191:      */
        !          1192:     if( reset_flags & SCSI_RESET_SUGGEST_BUS_RESET )
        !          1193:       {
        !          1194:        /* 
        !          1195:         * This does a scsi reset for all devices on the bus.
        !          1196:         * In principle, we could also reset the 1542 - should
        !          1197:         * we do this?  Try this first, and we can add that later
        !          1198:         * if it turns out to be useful.
        !          1199:         */
        !          1200:        outb(HRST | SCRST, CONTROL(SCpnt->host->io_port));
        !          1201: 
        !          1202:        /*
        !          1203:         * Wait for the thing to settle down a bit.  Unfortunately
        !          1204:         * this is going to basically lock up the machine while we
        !          1205:         * wait for this to complete.  To be 100% correct, we need to
        !          1206:         * check for timeout, and if we are doing something like this
        !          1207:         * we are pretty desperate anyways.
        !          1208:         */
        !          1209:        WAIT(STATUS(SCpnt->host->io_port), 
        !          1210:             STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
        !          1211: 
        !          1212:        /*
        !          1213:         * We need to do this too before the 1542 can interact with
        !          1214:         * us again.
        !          1215:         */
        !          1216:        setup_mailboxes(SCpnt->host->io_port, SCpnt->host);
        !          1217: 
        !          1218:        /*
        !          1219:         * Now try to pick up the pieces.  Restart all commands
        !          1220:         * that are currently active on the bus, and reset all of
        !          1221:         * the datastructures.  We have some time to kill while
        !          1222:         * things settle down, so print a nice message.
        !          1223:         */
        !          1224:        printk("Sent BUS RESET to scsi host %d\n", SCpnt->host->host_no);
        !          1225: 
        !          1226:        for(i=0; i< AHA1542_MAILBOXES; i++)
        !          1227:          if(HOSTDATA(SCpnt->host)->SCint[i] != NULL)
        !          1228:            {
        !          1229:              Scsi_Cmnd * SCtmp;
        !          1230:              SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
        !          1231:              SCtmp->result = DID_RESET << 16;
        !          1232:              if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
        !          1233:              printk("Sending DID_RESET for target %d\n", SCpnt->target);
        !          1234:              SCtmp->scsi_done(SCpnt);
        !          1235:              
        !          1236:              HOSTDATA(SCpnt->host)->SCint[i] = NULL;
        !          1237:              HOSTDATA(SCpnt->host)->mb[i].status = 0;
        !          1238:            }
        !          1239:        /*
        !          1240:         * Now tell the mid-level code what we did here.  Since
        !          1241:         * we have restarted all of the outstanding commands,
        !          1242:         * then report SUCCESS.
        !          1243:         */
        !          1244:        return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
        !          1245: fail:
        !          1246:        printk("aha1542.c: Unable to perform hard reset.\n");
        !          1247:        printk("Power cycle machine to reset\n");
        !          1248:        return (SCSI_RESET_ERROR | SCSI_RESET_BUS_RESET);
        !          1249: 
        !          1250: 
        !          1251:       }
        !          1252:     else
        !          1253:       {
        !          1254:        /* This does a selective reset of just the one device */
        !          1255:        /* First locate the ccb for this command */
        !          1256:        for(i=0; i< AHA1542_MAILBOXES; i++)
        !          1257:          if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
        !          1258:            {
        !          1259:              HOSTDATA(SCpnt->host)->ccb[i].op = 0x81;  /* BUS DEVICE RESET */
        !          1260:              /* Now tell the 1542 to flush all pending commands for this target */
        !          1261:              aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
        !          1262:              
        !          1263:              /* Here is the tricky part.  What to do next.  Do we get an interrupt
        !          1264:                 for the commands that we aborted with the specified target, or
        !          1265:                 do we generate this on our own?  Try it without first and see
        !          1266:                 what happens */
        !          1267:              printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
        !          1268:              
        !          1269:              /* If the first does not work, then try the second.  I think the
        !          1270:                 first option is more likely to be correct. Free the command
        !          1271:                 block for all commands running on this target... */
        !          1272:              for(i=0; i< AHA1542_MAILBOXES; i++)
        !          1273:                if(HOSTDATA(SCpnt->host)->SCint[i] &&
        !          1274:                   HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
        !          1275:                  {
        !          1276:                    Scsi_Cmnd * SCtmp;
        !          1277:                    SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
        !          1278:                    SCtmp->result = DID_RESET << 16;
        !          1279:                    if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
        !          1280:                    printk("Sending DID_RESET for target %d\n", SCpnt->target);
        !          1281:                    SCtmp->scsi_done(SCpnt);
        !          1282:                    
        !          1283:                    HOSTDATA(SCpnt->host)->SCint[i] = NULL;
        !          1284:                    HOSTDATA(SCpnt->host)->mb[i].status = 0;
        !          1285:                  }
        !          1286:              return SCSI_RESET_SUCCESS;
        !          1287:            }
        !          1288:       }
        !          1289:     /* No active command at this time, so this means that each time we got
        !          1290:        some kind of response the last time through.  Tell the mid-level code
        !          1291:        to request sense information in order to decide what to do next. */
        !          1292:     return SCSI_RESET_PUNT;
        !          1293: }
        !          1294: 
        !          1295: #include "sd.h"
        !          1296: 
        !          1297: int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip)
        !          1298: {
        !          1299:   int translation_algorithm;
        !          1300:   int size = disk->capacity;
        !          1301: 
        !          1302:   translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
        !          1303: 
        !          1304:   if((size>>11) > 1024 && translation_algorithm == BIOS_TRANSLATION_25563) {
        !          1305:     /* Please verify that this is the same as what DOS returns */
        !          1306:     ip[0] = 255;
        !          1307:     ip[1] = 63;
        !          1308:     ip[2] = size /255/63;
        !          1309:   } else {
        !          1310:     ip[0] = 64;
        !          1311:     ip[1] = 32;
        !          1312:     ip[2] = size >> 11;
        !          1313:   }
        !          1314: 
        !          1315:   return 0;
        !          1316: }
        !          1317: 
        !          1318: 
        !          1319: #ifdef MODULE
        !          1320: /* Eventually this will go into an include file, but this will be later */
        !          1321: Scsi_Host_Template driver_template = AHA1542;
        !          1322: 
        !          1323: #include "scsi_module.c"
        !          1324: #endif
        !          1325: 

unix.superglobalmegacorp.com

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