Annotation of Net2/arch/i386/isa/ultra14f.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Ported for use with the UltraStor 14f by Gary Close ([email protected])
        !             3:  * Thanks to Julian Elischer for advice and help with this port.
        !             4:  *
        !             5:  * Written by Julian Elischer ([email protected])
        !             6:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
        !             7:  *
        !             8:  * TRW Financial Systems, in accordance with their agreement with Carnegie
        !             9:  * Mellon University, makes this software available to CMU to distribute
        !            10:  * or use in any manner that they see fit as long as this message is kept with
        !            11:  * the software. For this reason TFS also grants any other persons or
        !            12:  * organisations permission to use or modify this software.
        !            13:  *
        !            14:  * TFS supplies this software to be publicly redistributed
        !            15:  * on the understanding that TFS is not responsible for the correct
        !            16:  * functioning of this software in any circumstances.
        !            17:  *
        !            18:  *
        !            19:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !            20:  * --------------------         -----   ----------------------
        !            21:  * CURRENT PATCH LEVEL:         1       00098
        !            22:  * --------------------         -----   ----------------------
        !            23:  *
        !            24:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
        !            25:  * commenced: Sun Sep 27 18:14:01 PDT 1992
        !            26:  */
        !            27:  
        !            28: #include <sys/types.h>
        !            29: #include <uha.h>
        !            30: 
        !            31: #include <sys/param.h>
        !            32: #include <sys/systm.h>
        !            33: #include <sys/errno.h>
        !            34: #include <sys/ioctl.h>
        !            35: #include <sys/buf.h>
        !            36: #include <sys/proc.h>
        !            37: #include <sys/user.h>
        !            38: 
        !            39: #ifdef  MACH    /* EITHER CMU OR OSF */
        !            40: #include <i386/ipl.h>
        !            41: #include <i386at/scsi.h>
        !            42: #include <i386at/scsiconf.h>
        !            43: 
        !            44: #ifdef  OSF     /* OSF ONLY */
        !            45: #include <sys/table.h>
        !            46: #include <i386/handler.h>
        !            47: #include <i386/dispatcher.h>
        !            48: #include <i386/AT386/atbus.h>
        !            49: 
        !            50: #else   OSF     /* CMU ONLY */
        !            51: #include <i386at/atbus.h>
        !            52: #include <i386/pio.h>
        !            53: #endif  OSF
        !            54: #endif  MACH    /* end of MACH specific */
        !            55: 
        !            56: #ifdef  __386BSD__      /* 386BSD specific */
        !            57: #define isa_dev isa_device
        !            58: #define dev_unit id_unit
        !            59: #define dev_addr id_iobase
        !            60: 
        !            61: #include <i386/include/pio.h>
        !            62: #include <i386/isa/isa_device.h>
        !            63: #include <scsi/scsi_all.h>
        !            64: #include <scsi/scsiconf.h>
        !            65: #endif  __386BSD__
        !            66: 
        !            67: /**/
        !            68: 
        !            69: #ifdef  __386BSD__
        !            70: #ifdef DDB
        !            71: int     Debugger();
        !            72: #else
        !            73: #define Debugger() panic("should call debugger here")
        !            74: #endif /*!DDB*/
        !            75: #endif  __386BSD__
        !            76: 
        !            77: #ifdef  MACH
        !            78: int     Debugger();
        !            79: #endif  MACH
        !            80: 
        !            81: typedef struct {unsigned char addr[4]; } physaddr;
        !            82: typedef struct {unsigned char len[4]; } physlen;
        !            83: 
        !            84: 
        !            85: #ifdef        MACH
        !            86: extern physaddr kvtophys();
        !            87: #define PHYSTOKV(x)   phystokv(x)
        !            88: #define KVTOPHYS(x)   kvtophys(x)
        !            89: #endif MACH
        !            90: 
        !            91: #ifdef        __386BSD__
        !            92: #define PHYSTOKV(x)   (x | 0xFE000000)
        !            93: #define KVTOPHYS(x)   vtophys(x)
        !            94: #endif        __386BSD__
        !            95: 
        !            96: extern int delaycount;  /* from clock setup code */
        !            97: #define NUM_CONCURRENT 16      /* number of concurrent ops per board */
        !            98: #define UHA_NSEG        33      /* number of dma segments supported     */
        !            99: #define FUDGE(X)        (X>>1)  /* our loops are slower than spinwait() */
        !           100: /**/
        !           101: /************************** board definitions *******************************/
        !           102: /*
        !           103:  * I/O Port Interface
        !           104: */
        !           105:  #define UHA_LMASK              (0x000)  /* local doorbell mask reg */
        !           106:  #define UHA_LINT               (0x001)  /* local doorbell int/stat reg */
        !           107:  #define UHA_SMASK              (0x002)  /* system doorbell mask reg */
        !           108:  #define UHA_SINT               (0x003)  /* system doorbell int/stat reg */
        !           109:  #define UHA_ID0                (0x004)  /* product id reg 0 */
        !           110:  #define UHA_ID1                (0x005)  /* product id reg 1 */
        !           111:  #define UHA_CONF1              (0x006)  /* config reg 1 */
        !           112:  #define UHA_CONF2              (0x007)  /* config reg 2 */
        !           113:  #define UHA_OGM0               (0x008)  /* outgoing mail ptr 0 least sig */
        !           114:  #define UHA_OGM1               (0x009)  /* outgoing mail ptr 1 least mid */
        !           115:  #define UHA_OGM2               (0x00a)  /* outgoing mail ptr 2 most mid  */
        !           116:  #define UHA_OGM3               (0x00b)  /* outgoing mail ptr 3 most sig  */
        !           117:  #define UHA_ICM0               (0x00c)  /* incoming mail ptr 0 */
        !           118:  #define UHA_ICM1               (0x00d)  /* incoming mail ptr 1 */
        !           119:  #define UHA_ICM2               (0x00e)  /* incoming mail ptr 2 */
        !           120:  #define UHA_ICM3               (0x00f)  /* incoming mail ptr 3 */
        !           121: 
        !           122:  /*
        !           123: * UHA_LMASK bits (read only) 
        !           124: */
        !           125: 
        !           126: #define UHA_LDIE                0x80    /* local doorbell int enabled */
        !           127: #define UHA_SRSTE               0x40    /* soft reset enabled */
        !           128: #define UHA_ABORTEN             0x10    /* abort MSCP enabled */
        !           129: #define UHA_OGMINTEN            0x01    /* outgoing mail interrupt enabled */
        !           130: 
        !           131: /*
        !           132: * UHA_LINT bits (read)
        !           133: */
        !           134: 
        !           135: #define UHA_LDIP                0x80    /* local doorbell int pending */
        !           136: 
        !           137: /*
        !           138: * UHA_LINT bits (write)
        !           139: */
        !           140: 
        !           141: #define UHA_ADRST               0x40    /* adapter soft reset */
        !           142: #define UHA_SBRST               0x20    /* scsi bus reset */
        !           143: #define UHA_ASRST               0x60    /* adapter and scsi reset */
        !           144: #define UHA_ABORT               0x10    /* abort MSCP */
        !           145: #define UHA_OGMINT              0x01    /* tell adapter to get mail */
        !           146: 
        !           147: /*
        !           148: * UHA_SMASK bits (read)
        !           149: */
        !           150: 
        !           151: #define UHA_SINTEN              0x80    /* system doorbell interupt Enabled */
        !           152: #define UHA_ABORT_COMPLETE_EN   0x10    /* abort MSCP command complete int Enabled */
        !           153: #define UHA_ICM_ENABLED         0x01    /* ICM interrupt enabled
        !           154: 
        !           155: /*
        !           156: * UHA_SMASK bits (write)
        !           157: */
        !           158: 
        !           159: #define UHA_ENSINT              0x80    /* enable system doorbell interrupt */
        !           160: #define UHA_EN_ABORT_COMPLETE   0x10    /* enable abort MSCP complete int */
        !           161: #define UHA_ENICM               0x01    /* enable ICM interrupt */
        !           162: 
        !           163: /*
        !           164: * UHA_SINT bits (read)
        !           165: */
        !           166: 
        !           167: #define UHA_SINTP               0x80    /* system doorbell int pending */
        !           168: #define UHA_ABORT_SUCC          0x10    /* abort MSCP successful */
        !           169: #define UHA_ABORT_FAIL          0x18    /* abort MSCP failed */
        !           170: 
        !           171: /*
        !           172: * UHA_SINT bits (write)
        !           173: */
        !           174: 
        !           175: #define UHA_ABORT_ACK           0x18    /* acknowledge status and clear */
        !           176: #define UHA_ICM_ACK             0x01    /* acknowledge ICM and clear */
        !           177: 
        !           178: /* 
        !           179: * UHA_CONF1 bits (read only)
        !           180: */
        !           181: 
        !           182: #define UHA_DMA_CH5             0x00    /* DMA channel 5 */
        !           183: #define UHA_DMA_CH6             0x40    /* 6 */
        !           184: #define UHA_DMA_CH7             0x80    /* 7 */
        !           185: #define UHA_IRQ15               0x00    /* IRQ 15 */
        !           186: #define UHA_IRQ14               0x10    /* 14 */
        !           187: #define UHA_IRQ11               0x20    /* 11 */
        !           188: #define UHA_IRQ10               0x30    /* 10 */
        !           189: 
        !           190: /***********************************
        !           191: * ha_status error codes
        !           192: \***********************************/
        !           193: 
        !           194: #define UHA_NO_ERR             0x00            /* No error supposedly */
        !           195: #define UHA_SBUS_ABORT_ERR     0x84            /* scsi bus abort error */
        !           196: #define UHA_SBUS_TIMEOUT       0x91            /* scsi bus selection timeout */
        !           197: #define UHA_SBUS_OVER_UNDER    0x92            /* scsi bus over/underrun */
        !           198: #define UHA_BAD_SCSI_CMD       0x96            /* illegal scsi command */
        !           199: #define UHA_AUTO_SENSE_ERR     0x9b            /* auto request sense err */
        !           200: #define UHA_SBUS_RES_ERR       0xa3            /* scsi bus reset error */
        !           201: #define UHA_BAD_SG_LIST                0xff            /* invalid scatter gath list */
        !           202: 
        !           203: /**/
        !           204: 
        !           205: struct  uha_dma_seg
        !           206: {
        !           207:        physaddr                        addr;
        !           208:        physlen                         len;
        !           209: };
        !           210: /**/
        !           211: 
        !           212: struct  mscp
        !           213: {
        !           214:        unsigned char           opcode:3;
        !           215:        #define U14_HAC         0x01            /*host adapter command*/
        !           216:        #define U14_TSP         0x02            /*target scsi pass through command*/
        !           217:        #define U14_SDR         0x04            /*scsi device reset*/
        !           218:        unsigned char           xdir:2;         /*xfer direction*/
        !           219:        #define U14_SDET        0x00            /*determined by scsi command*/
        !           220:        #define U14_SDIN        0x01            /*scsi data in*/
        !           221:        #define U14_SDOUT       0x02            /*scsi data out*/
        !           222:        #define U14_NODATA      0x03            /*no data xfer*/
        !           223:        unsigned char           dcn:1;          /*disable disconnect for this command*/
        !           224:        unsigned char           ca:1;           /*Cache control*/
        !           225:        unsigned char           sgth:1;         /*scatter gather flag*/
        !           226:        unsigned char           target:3;
        !           227:        unsigned char           chan:2;         /*scsi channel (always 0 for 14f)*/
        !           228:        unsigned char           lun:3;
        !           229:        physaddr                data;
        !           230:        physlen                 datalen;
        !           231:        physaddr                link;
        !           232:        unsigned char           link_id;
        !           233:        unsigned char           sg_num;         /*number of scat gath segs */
        !           234:                                                /*in s-g list if sg flag is*/
        !           235:                                                /*set. starts at 1, 8bytes per*/
        !           236:        unsigned char           senselen;
        !           237:        unsigned char           cdblen;
        !           238:        unsigned char           cdb[12];
        !           239:        unsigned char           ha_status;
        !           240:        unsigned char           targ_status;
        !           241:        physaddr                sense;          /* if 0 no auto sense */
        !           242:        /*-----------------end of hardware supported fields----------------*/
        !           243:        struct  mscp     *next;  /* in free list */
        !           244:        struct  scsi_xfer *xs; /* the scsi_xfer for this cmd */
        !           245:        long    int     delta;  /* difference from previous*/
        !           246:        struct  mscp     *later,*sooner;
        !           247:        int             flags;
        !           248: #define MSCP_FREE        0
        !           249: #define MSCP_ACTIVE      1
        !           250: #define MSCP_ABORTED     2
        !           251:        struct  uha_dma_seg     uha_dma[UHA_NSEG];
        !           252:        struct  scsi_sense_data mscp_sense;
        !           253: };
        !           254: 
        !           255: struct  mscp     *uha_soonest    = (struct mscp *)0;
        !           256: struct  mscp     *uha_latest     = (struct mscp *)0;
        !           257: long    int     uha_furtherest  = 0; /* longest time in the timeout queue */
        !           258: /**/
        !           259: 
        !           260: struct  uha_data
        !           261: {
        !           262:        int     flags;
        !           263: #define UHA_INIT        0x01;
        !           264:        int     baseport;
        !           265:        struct  mscp mscps[NUM_CONCURRENT];
        !           266:        struct  mscp *free_mscp;
        !           267:        int     our_id;                 /* our scsi id */
        !           268:        int     vect;
        !           269:        int     dma;
        !           270: } uha_data[NUHA];
        !           271: 
        !           272: int     uhaprobe();
        !           273: int     uha_attach();
        !           274: int     uhaintr();
        !           275: int     uha_scsi_cmd();
        !           276: int     uha_timeout();
        !           277: int    uha_abort();
        !           278: struct  mscp *cheat;
        !           279: void    uhaminphys();
        !           280: long int uha_adapter_info();
        !           281: 
        !           282: unsigned long int scratch;
        !           283: 
        !           284: #ifdef  MACH
        !           285: struct  isa_driver      uhadriver = { uhaprobe, 0, uha_attach, "uha", 0, 0, 0};
        !           286: int (*uhaintrs[])() = {uhaintr, 0};
        !           287: #endif  MACH
        !           288: 
        !           289: #ifdef  __386BSD__
        !           290: struct  isa_driver      uhadriver = { uhaprobe, uha_attach, "uha"};
        !           291: #endif  __386BSD__
        !           292: 
        !           293: static uha_unit = 0;
        !           294: int     uha_debug = 0;
        !           295: #define UHA_SHOWMSCPS 0x01
        !           296: #define UHA_SHOWINTS 0x02
        !           297: #define UHA_SHOWCMDS 0x04
        !           298: #define UHA_SHOWMISC 0x08
        !           299: #define FAIL    1
        !           300: #define SUCCESS 0
        !           301: #define PAGESIZ 4096
        !           302: 
        !           303: struct  scsi_switch     uha_switch = 
        !           304: {
        !           305:        uha_scsi_cmd,
        !           306:        uhaminphys,
        !           307:        0,
        !           308:        0,
        !           309:        uha_adapter_info,
        !           310:        0,0,0
        !           311: };
        !           312: 
        !           313: /**/
        !           314: /***********************************************************************\
        !           315: * Function to send a command out through a mailbox                      *
        !           316: \***********************************************************************/
        !           317: uha_send_mbox(  int             unit
        !           318:                ,struct mscp     *mscp)
        !           319: {
        !           320:        int     port = uha_data[unit].baseport;
        !           321:        int     spincount = FUDGE(delaycount) * 1; /* 1ms should be enough */
        !           322:        int     s = splbio();
        !           323:                
        !           324:        while(      ((inb(port + UHA_LINT) & (UHA_LDIP))
        !           325:                                        != (0))
        !           326:                && (spincount--));
        !           327:        if(spincount == -1)
        !           328:        {
        !           329:                printf("uha%d: board not responding\n",unit);
        !           330:                Debugger();
        !           331:        }
        !           332: 
        !           333:        outl(port + UHA_OGM0,KVTOPHYS(mscp)); 
        !           334:        outb(port + UHA_LINT, (UHA_OGMINT));
        !           335:        splx(s);
        !           336: }
        !           337: 
        !           338: /***********************************************************************\
        !           339: * Function to send abort to 14f                                         *
        !           340: \***********************************************************************/
        !           341: 
        !           342: uha_abort(     int             unit
        !           343:                ,struct mscp    *mscp)
        !           344: {
        !           345:        int     port = uha_data[unit].baseport;
        !           346:        int     spincount = FUDGE(delaycount) * 1;
        !           347:        int     abortcount = FUDGE(delaycount) * 2000;
        !           348:        int     s = splbio();
        !           349:        
        !           350:        while(((inb(port + UHA_LINT) & (UHA_LDIP))
        !           351:                                != (0))
        !           352:                && (spincount--));
        !           353:        if(spincount == -1);
        !           354:        {
        !           355:                printf("uha%d: board not responding\n",unit);
        !           356:                Debugger();
        !           357:        }
        !           358: 
        !           359:        outl(port + UHA_OGM0,KVTOPHYS(mscp));
        !           360:        outb(port + UHA_LINT,UHA_ABORT);
        !           361: 
        !           362:        while((abortcount--) && (!(inb(port + UHA_SINT) & UHA_ABORT_FAIL)));
        !           363:        if(abortcount == -1)
        !           364:        {
        !           365:                printf("uha%d: board not responding\n",unit);
        !           366:                Debugger();
        !           367:        }
        !           368:        if((inb(port + UHA_SINT) & 0x10) != 0)
        !           369:        {
        !           370:                outb(port + UHA_SINT,UHA_ABORT_ACK);
        !           371:                return(1);
        !           372:        }
        !           373:        else
        !           374:        {
        !           375:                outb(port + UHA_SINT,UHA_ABORT_ACK);
        !           376:                return(0);
        !           377:        }
        !           378: }
        !           379: 
        !           380: /***********************************************************************\
        !           381: * Function to poll for command completion when in poll mode             *
        !           382: \***********************************************************************/
        !           383: uha_poll(int unit ,int wait) /* in msec  */
        !           384: {
        !           385:        int     port = uha_data[unit].baseport;
        !           386:        int     spincount = FUDGE(delaycount) * wait; /* in msec */
        !           387:        int     stport = port + UHA_SINT;
        !           388:        int     start = spincount;
        !           389: 
        !           390: retry:
        !           391:        while( (spincount--) && (!(inb(stport) &  UHA_SINTP)));
        !           392:        if(spincount == -1)
        !           393:        {
        !           394:                printf("uha%d: board not responding\n",unit);
        !           395:                return(EIO);
        !           396:        }
        !           397: if ((int)cheat != PHYSTOKV(inl(port + UHA_ICM0)))
        !           398: {
        !           399:        printf("discarding %x ",inl(port + UHA_ICM0));
        !           400:        outb(port + UHA_SINT, UHA_ICM_ACK);
        !           401:        spinwait(50);
        !           402:        goto retry;
        !           403: }/* don't know this will work */
        !           404:        uhaintr(unit);
        !           405:        return(0);
        !           406: }
        !           407: 
        !           408: /*******************************************************\
        !           409: * Check if the device can be found at the port given    *
        !           410: * and if so, set it up ready for further work           *
        !           411: * as an argument, takes the isa_dev structure from      *
        !           412: * autoconf.c                                            *
        !           413: \*******************************************************/
        !           414: uhaprobe(dev)
        !           415: struct isa_dev *dev;
        !           416: {
        !           417:        int     unit = uha_unit;
        !           418:        dev->dev_unit = unit;
        !           419:        uha_data[unit].baseport = dev->dev_addr;
        !           420:        if(unit >= NUHA)
        !           421:        {
        !           422:                printf("uha: unit number (%d) too high\n",unit);
        !           423:                return(0);
        !           424:        }
        !           425:        
        !           426:        /*try and initialize unit at this location*/
        !           427:        if (uha_init(unit) != 0)
        !           428:        {
        !           429:                return(0);
        !           430:        }
        !           431: 
        !           432:        /* if its there put in it's interrupt and DRQ vectors */
        !           433: 
        !           434:        dev->id_irq = (1 << uha_data[unit].vect);
        !           435:        dev->id_drq = uha_data[unit].dma;
        !           436: 
        !           437:        
        !           438:        uha_unit ++;
        !           439: return(1);
        !           440: }
        !           441: 
        !           442: /***********************************************\
        !           443: * Attach all the sub-devices we can find        *
        !           444: \***********************************************/
        !           445: uha_attach(dev)
        !           446: struct  isa_dev *dev;
        !           447: {
        !           448:        int     unit = dev->dev_unit;
        !           449: 
        !           450: 
        !           451: #ifdef  __386BSD__
        !           452:        printf("uha%d: probing for scsi devices..", unit);
        !           453: #endif  __386BSD__
        !           454: 
        !           455:        /***********************************************\
        !           456:        * ask the adapter what subunits are present     *
        !           457:        \***********************************************/
        !           458:        scsi_attachdevs( unit, uha_data[unit].our_id, &uha_switch);
        !           459: 
        !           460: #if defined(OSF)
        !           461:        uha_attached[unit]=1;
        !           462: #endif /* defined(OSF) */
        !           463:        if(!unit)  /* only one for all boards */
        !           464:        {
        !           465:                uha_timeout(0);
        !           466:        }
        !           467:        return;
        !           468: }
        !           469: 
        !           470: /***********************************************\
        !           471: * Return some information to the caller about   *
        !           472: * the adapter and it's capabilities             *
        !           473: \***********************************************/
        !           474: long int uha_adapter_info(unit)
        !           475: int     unit;
        !           476: {
        !           477:        return(2);      /* 2 outstanding requests at a time per device */
        !           478: }
        !           479: 
        !           480: /***********************************************\
        !           481: * Catch an interrupt from the adaptor           *
        !           482: \***********************************************/
        !           483: uhaintr(unit)
        !           484: {
        !           485:        struct mscp      *mscp;
        !           486:        u_char          uhastat;
        !           487:        unsigned long int        mboxval;
        !           488: 
        !           489:        int     port = uha_data[unit].baseport;
        !           490: 
        !           491: 
        !           492:        if(scsi_debug & PRINTROUTINES)
        !           493:                printf("uhaintr ");
        !           494: 
        !           495: #if defined(OSF)
        !           496:        if (!uha_attached[unit])
        !           497:        {
        !           498:                return(1);
        !           499:        }
        !           500: #endif /* defined(OSF) */
        !           501:        while(inb(port + UHA_SINT) & UHA_SINTP)
        !           502:        {
        !           503:                /***********************************************\
        !           504:                * First get all the information and then        *
        !           505:                * acknowlege the interrupt                      *
        !           506:                \***********************************************/
        !           507:                uhastat = inb(port + UHA_SINT);
        !           508:                mboxval = inl(port + UHA_ICM0);
        !           509:                outb(port + UHA_SINT,UHA_ICM_ACK);
        !           510: 
        !           511:                if(scsi_debug & TRACEINTERRUPTS)
        !           512:                        printf("status = 0x%x ",uhastat);
        !           513:                /***********************************************\
        !           514:                * Process the completed operation               *
        !           515:                \***********************************************/
        !           516:        
        !           517:                        mscp = (struct mscp *)(PHYSTOKV(mboxval)); 
        !           518: 
        !           519:                        if(uha_debug & UHA_SHOWCMDS )
        !           520:                        {
        !           521:                                uha_show_scsi_cmd(mscp->xs);
        !           522:                        }
        !           523:                        if((uha_debug & UHA_SHOWMSCPS) && mscp)
        !           524:                                printf("<int mscp(%x)>",mscp);
        !           525:                        uha_remove_timeout(mscp);
        !           526: 
        !           527:                        uha_done(unit,mscp);
        !           528:        }
        !           529:        return(1);
        !           530: }
        !           531: 
        !           532: /***********************************************\
        !           533: * We have a mscp which has been processed by the *
        !           534: * adaptor, now we look to see how the operation *
        !           535: * went.                                         *
        !           536: \***********************************************/
        !           537: 
        !           538: uha_done(unit,mscp)
        !           539: int     unit;
        !           540: struct mscp *mscp;
        !           541: {
        !           542:        struct  scsi_sense_data *s1,*s2;
        !           543:        struct  scsi_xfer *xs = mscp->xs;
        !           544: 
        !           545:        if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS))
        !           546:                printf("uha_done ");
        !           547:        /***********************************************\
        !           548:        * Otherwise, put the results of the operation   *
        !           549:        * into the xfer and call whoever started it     *
        !           550:        \***********************************************/
        !           551:        if ( (mscp->ha_status == UHA_NO_ERR) || (xs->flags & SCSI_ERR_OK))
        !           552:        {               /* All went correctly  OR errors expected */
        !           553:                xs->resid = 0;
        !           554:                xs->error = 0;
        !           555:        }
        !           556:        else
        !           557:        {
        !           558: 
        !           559:                s1 = &(mscp->mscp_sense);
        !           560:                s2 = &(xs->sense);
        !           561: 
        !           562:                if(mscp->ha_status != UHA_NO_ERR)
        !           563:                {
        !           564:                        switch(mscp->ha_status)
        !           565:                        {
        !           566:                        case    UHA_SBUS_TIMEOUT:           /* No response */
        !           567:                                if (uha_debug & UHA_SHOWMISC)
        !           568:                                {
        !           569:                                        printf("timeout reported back\n");
        !           570:                                }
        !           571:                                xs->error = XS_TIMEOUT;
        !           572:                                break;
        !           573:                        case    UHA_SBUS_OVER_UNDER:
        !           574:                                if (uha_debug & UHA_SHOWMISC)
        !           575:                                {
        !           576:                                        printf("scsi bus xfer over/underrun\n");
        !           577:                                }
        !           578:                                xs->error = XS_DRIVER_STUFFUP;
        !           579:                                break;
        !           580:                        case    UHA_BAD_SG_LIST:
        !           581:                                if (uha_debug & UHA_SHOWMISC)
        !           582:                                {
        !           583:                                        printf("bad sg list reported back\n");
        !           584:                                }
        !           585:                                xs->error = XS_DRIVER_STUFFUP;
        !           586:                                break;
        !           587:                        default:        /* Other scsi protocol messes */
        !           588:                                xs->error = XS_DRIVER_STUFFUP;
        !           589:                                if (uha_debug & UHA_SHOWMISC)
        !           590:                                {
        !           591:                                        printf("unexpected ha_status: %x\n",
        !           592:                                                mscp->ha_status);
        !           593:                                }
        !           594:                        }
        !           595: 
        !           596:                }
        !           597:                else
        !           598:                {
        !           599: 
        !           600:                        if (mscp->targ_status != 0)
        !           601: /**************************************************************************\
        !           602: * I have no information for any possible value of target status field     *
        !           603: * other than 0 means no error!! So I guess any error is unexpected in that *
        !           604: * event!!                                                                 *
        !           605: \**************************************************************************/
        !           606: 
        !           607:                        {       
        !           608:                                if (uha_debug & UHA_SHOWMISC)
        !           609:                                {
        !           610:                                        printf("unexpected targ_status: %x\n",
        !           611:                                                mscp->targ_status);
        !           612:                                }
        !           613:                                xs->error = XS_DRIVER_STUFFUP;
        !           614:                        }
        !           615:                }
        !           616:        }
        !           617: done:   xs->flags |= ITSDONE;
        !           618:        uha_free_mscp(unit,mscp, xs->flags);
        !           619:        if(xs->when_done)
        !           620:                (*(xs->when_done))(xs->done_arg,xs->done_arg2);
        !           621: }
        !           622: 
        !           623: /***********************************************\
        !           624: * A mscp (and hence a mbx-out is put onto the    *
        !           625: * free list.                                    *
        !           626: \***********************************************/
        !           627: uha_free_mscp(unit,mscp, flags)
        !           628: struct mscp *mscp;
        !           629: {
        !           630:        unsigned int opri;
        !           631:        
        !           632:        if(scsi_debug & PRINTROUTINES)
        !           633:                printf("mscp%d(0x%x)> ",unit,flags);
        !           634:        if (!(flags & SCSI_NOMASK)) 
        !           635:                opri = splbio();
        !           636: 
        !           637:        mscp->next = uha_data[unit].free_mscp;
        !           638:        uha_data[unit].free_mscp = mscp;
        !           639:        mscp->flags = MSCP_FREE;
        !           640:        /***********************************************\
        !           641:        * If there were none, wake abybody waiting for  *
        !           642:        * one to come free, starting with queued entries*
        !           643:        \***********************************************/
        !           644:        if (!mscp->next) {
        !           645:                wakeup(&uha_data[unit].free_mscp);
        !           646:        }
        !           647:        if (!(flags & SCSI_NOMASK)) 
        !           648:                splx(opri);
        !           649: }
        !           650: 
        !           651: /***********************************************\
        !           652: * Get a free mscp (and hence mbox-out entry)     *
        !           653: \***********************************************/
        !           654: struct mscp *
        !           655: uha_get_mscp(unit,flags)
        !           656: {
        !           657:        unsigned opri;
        !           658:        struct mscp *rc;
        !           659: 
        !           660:        if(scsi_debug & PRINTROUTINES)
        !           661:                printf("<mscp%d(0x%x) ",unit,flags);
        !           662:        if (!(flags & SCSI_NOMASK)) 
        !           663:                opri = splbio();
        !           664:        /***********************************************\
        !           665:        * If we can and have to, sleep waiting for one  *
        !           666:        * to come free                                  *
        !           667:        \***********************************************/
        !           668:        while ((!(rc = uha_data[unit].free_mscp)) && (!(flags & SCSI_NOSLEEP)))
        !           669:        {
        !           670:                sleep(&uha_data[unit].free_mscp, PRIBIO);
        !           671:        }
        !           672:        if (rc) 
        !           673:        {
        !           674:                uha_data[unit].free_mscp = rc->next;
        !           675:                rc->flags = MSCP_ACTIVE;
        !           676:        }
        !           677:        if (!(flags & SCSI_NOMASK)) 
        !           678:                splx(opri);
        !           679:        return(rc);
        !           680: }
        !           681:                
        !           682: 
        !           683: 
        !           684: /***********************************************\
        !           685: * Start the board, ready for normal operation   *
        !           686: \***********************************************/
        !           687: 
        !           688: uha_init(unit)
        !           689: int    unit;
        !           690: {      
        !           691:        unsigned char ad[4];
        !           692:        volatile unsigned char model;
        !           693:        volatile unsigned char submodel;
        !           694:        unsigned char config_reg1;
        !           695:        unsigned char config_reg2;
        !           696:        unsigned char dma_ch;
        !           697:        unsigned char irq_ch;
        !           698:        unsigned char uha_id;
        !           699:        int     port = uha_data[unit].baseport;
        !           700:        int     i;
        !           701:        int     resetcount = FUDGE(delaycount) * 4000;
        !           702: 
        !           703:        model = inb(port + UHA_ID0);
        !           704:        submodel = inb(port + UHA_ID1);
        !           705:                 if ((model != 0x56) & (submodel != 0x40))
        !           706:                      { /* printf("ultrastor 14f not responding\n"); */
        !           707:                        return(ENXIO); }
        !           708: 
        !           709:        printf("uha%d reading board settings, ",unit);
        !           710: 
        !           711:        config_reg1 = inb(port + UHA_CONF1);
        !           712:        config_reg2 = inb(port + UHA_CONF2);
        !           713:        dma_ch = (config_reg1 & 0xc0);
        !           714:        irq_ch = (config_reg1 & 0x30);
        !           715:        uha_id = (config_reg2 & 0x07);
        !           716: 
        !           717:        switch(dma_ch)
        !           718:        {
        !           719:        case    UHA_DMA_CH5:
        !           720:                uha_data[unit].dma = 5;
        !           721:                printf("dma=5 ");
        !           722:                break;
        !           723:        case    UHA_DMA_CH6:
        !           724:                uha_data[unit].dma = 6;
        !           725:                printf("dma=6 ");
        !           726:                break;
        !           727:        case    UHA_DMA_CH7:
        !           728:                uha_data[unit].dma = 7;
        !           729:                printf("dma=7 ");
        !           730:                break;
        !           731:        default:
        !           732:                printf("illegal dma jumper setting\n");
        !           733:                return(EIO);
        !           734:        }
        !           735:        switch(irq_ch)
        !           736:        {
        !           737:        case    UHA_IRQ10:
        !           738:                uha_data[unit].vect = 10;
        !           739:                printf("int=10 ");
        !           740:                break;
        !           741:        case    UHA_IRQ11:
        !           742:                uha_data[unit].vect = 11;
        !           743:                printf("int=11 ");
        !           744:                break;
        !           745:        case    UHA_IRQ14:
        !           746:                uha_data[unit].vect = 14;
        !           747:                printf("int=14 ");
        !           748:                break;
        !           749:        case    UHA_IRQ15:
        !           750:                uha_data[unit].vect = 15;
        !           751:                printf("int=15 ");
        !           752:                break;
        !           753:        default:
        !           754:                printf("illegal int jumper setting\n");
        !           755:                return(EIO);
        !           756:        }
        !           757:        /* who are we on the scsi bus */
        !           758:        printf("id=%x\n",uha_id);
        !           759:        uha_data[unit].our_id = uha_id;
        !           760: 
        !           761:        
        !           762:        /***********************************************\
        !           763:        * link up all our MSCPs into a free list         *
        !           764:        \***********************************************/
        !           765:        for (i=0; i < NUM_CONCURRENT; i++)
        !           766:        {
        !           767:                uha_data[unit].mscps[i].next = uha_data[unit].free_mscp;
        !           768:                uha_data[unit].free_mscp = &uha_data[unit].mscps[i];
        !           769:                uha_data[unit].free_mscp->flags = MSCP_FREE;
        !           770:        }
        !           771: 
        !           772:        /***********************************************\
        !           773:        * Note that we are going and return (to probe)  *
        !           774:        \***********************************************/
        !           775:        outb(port + UHA_LINT, UHA_ASRST);       
        !           776:        while( (resetcount--) && (!(inb(port + UHA_LINT))));
        !           777:        if(resetcount == -1)
        !           778:        {
        !           779:                printf("uha%d: board timed out during reset\n",unit);
        !           780:                return(ENXIO);
        !           781:        }
        !           782: 
        !           783:        outb(port + UHA_SMASK, 0x81); /* make sure interrupts are enabled */
        !           784:        uha_data[unit].flags |= UHA_INIT;
        !           785:        return(0);
        !           786: }
        !           787: 
        !           788: 
        !           789: 
        !           790: #ifndef min
        !           791: #define min(x,y) (x < y ? x : y)
        !           792: #endif  min
        !           793: 
        !           794: 
        !           795: void uhaminphys(bp)
        !           796: struct  buf *bp;
        !           797: {
        !           798: #ifdef  MACH
        !           799: #if     !defined(OSF)
        !           800:        bp->b_flags |= B_NPAGES;                /* can support scat/gather */
        !           801: #endif  /* defined(OSF) */
        !           802: #endif  MACH
        !           803:        if(bp->b_bcount > ((UHA_NSEG-1) * PAGESIZ))
        !           804:        {
        !           805:                bp->b_bcount = ((UHA_NSEG-1) * PAGESIZ);
        !           806:        }
        !           807: }
        !           808: 
        !           809: /***********************************************\
        !           810: * start a scsi operation given the command and  *
        !           811: * the data address. Also needs the unit, target *
        !           812: * and lu                                        *
        !           813: \***********************************************/
        !           814: int     uha_scsi_cmd(xs)
        !           815: struct scsi_xfer *xs;
        !           816: {
        !           817:        struct  scsi_sense_data *s1,*s2;
        !           818:        struct mscp *mscp;
        !           819:        struct uha_dma_seg *sg;
        !           820:        int     seg;    /* scatter gather seg being worked on */
        !           821:        int i   = 0;
        !           822:        int rc  =  0;
        !           823:        int     thiskv;
        !           824:        unsigned long int        thisphys,nextphys;
        !           825:        int     unit =xs->adapter;
        !           826:        int     bytes_this_seg,bytes_this_page,datalen,flags;
        !           827:        struct  iovec   *iovp;
        !           828:        int     s;
        !           829:        unsigned int stat;
        !           830:        int     port = uha_data[unit].baseport;
        !           831:        unsigned long int templen;
        !           832: 
        !           833: 
        !           834:        if(scsi_debug & PRINTROUTINES)
        !           835:                printf("uha_scsi_cmd ");
        !           836:        /***********************************************\
        !           837:        * get a mscp (mbox-out) to use. If the transfer  *
        !           838:        * is from a buf (possibly from interrupt time)  *
        !           839:        * then we can't allow it to sleep               *
        !           840:        \***********************************************/
        !           841:        flags = xs->flags;
        !           842:        if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */
        !           843:        if(flags & ITSDONE)
        !           844:        {
        !           845:                printf("Already done?");
        !           846:                xs->flags &= ~ITSDONE;
        !           847:        }
        !           848:        if(!(flags & INUSE))
        !           849:        {
        !           850:                printf("Not in use?");
        !           851:                xs->flags |= INUSE;
        !           852:        }
        !           853:        if (!(mscp = uha_get_mscp(unit,flags)))
        !           854:        {
        !           855:                xs->error = XS_DRIVER_STUFFUP;
        !           856:                return(TRY_AGAIN_LATER);
        !           857:        }
        !           858: 
        !           859: cheat = mscp;
        !           860:        if(uha_debug & UHA_SHOWMSCPS)
        !           861:                                printf("<start mscp(%x)>",mscp);
        !           862:        if(scsi_debug & SHOWCOMMANDS)
        !           863:        {
        !           864:                uha_show_scsi_cmd(xs);
        !           865:        }
        !           866:        mscp->xs = xs;
        !           867:        /***********************************************\
        !           868:        * Put all the arguments for the xfer in the mscp *
        !           869:        \***********************************************/
        !           870: 
        !           871:        if (flags & SCSI_RESET)
        !           872:        {
        !           873:                mscp->opcode = 0x04;
        !           874:                mscp->ca = 0x01;
        !           875:        }
        !           876:        else
        !           877:        {
        !           878:                mscp->opcode = 0x02;
        !           879:                mscp->ca = 0x01;
        !           880:        }               
        !           881: 
        !           882:        if (flags & SCSI_DATA_IN)
        !           883:        {
        !           884:                mscp->xdir = 0x01;
        !           885:        }
        !           886:        if (flags & SCSI_DATA_OUT)
        !           887:        {
        !           888:                mscp->xdir = 0x02;
        !           889:        }
        !           890: 
        !           891:        if (xs->lu != 0)
        !           892:        {
        !           893:                xs->error = XS_DRIVER_STUFFUP;
        !           894:                uha_free_mscp(unit,mscp,flags);
        !           895:                return(HAD_ERROR);
        !           896:        }
        !           897:        
        !           898:        mscp->dcn       = 0x00;
        !           899:        mscp->chan      = 0x00;
        !           900:        mscp->target    = xs->targ;
        !           901:        mscp->lun       = xs->lu;
        !           902:        mscp->link.addr[0]      = 0x00;
        !           903:        mscp->link.addr[1]      = 0x00;
        !           904:        mscp->link.addr[2]      = 0x00;
        !           905:        mscp->link.addr[3]      = 0x00;
        !           906:        mscp->link_id   = 0x00;
        !           907:        mscp->cdblen             =       xs->cmdlen;
        !           908:        scratch                 =       KVTOPHYS(&(mscp->mscp_sense));
        !           909:        mscp->sense.addr[0]     =       (scratch & 0xff);
        !           910:        mscp->sense.addr[1]     =       ((scratch >> 8) & 0xff);
        !           911:        mscp->sense.addr[2]     =       ((scratch >> 16) & 0xff);
        !           912:        mscp->sense.addr[3]     =       ((scratch >> 24) & 0xff);
        !           913:        mscp->senselen          =       sizeof(mscp->mscp_sense);
        !           914:        mscp->ha_status         =       0x00;
        !           915:        mscp->targ_status       =       0x00;
        !           916: 
        !           917:        if(xs->datalen)
        !           918:        { /* should use S/G only if not zero length */
        !           919:                scratch                 =       KVTOPHYS(mscp->uha_dma);
        !           920:                mscp->data.addr[0]      =       (scratch & 0xff);
        !           921:                mscp->data.addr[1]      =       ((scratch >> 8) & 0xff);
        !           922:                mscp->data.addr[2]      =       ((scratch >> 16) & 0xff);
        !           923:                mscp->data.addr[3]      =       ((scratch >> 24) & 0xff);
        !           924:                sg              =       mscp->uha_dma ;
        !           925:                seg             =       0;
        !           926:                mscp->sgth      =       0x01;
        !           927: 
        !           928:                if(flags & SCSI_DATA_UIO)
        !           929:                {
        !           930:                        iovp = ((struct uio *)xs->data)->uio_iov;
        !           931:                        datalen = ((struct uio *)xs->data)->uio_iovcnt;
        !           932:                        xs->datalen = 0;
        !           933:                        while ((datalen) && (seg < UHA_NSEG))
        !           934:                        {
        !           935:                                scratch  = (unsigned long)iovp->iov_base;
        !           936:                                sg->addr.addr[0] = (scratch & 0xff); 
        !           937:                                sg->addr.addr[1] = ((scratch >> 8) & 0xff);
        !           938:                                sg->addr.addr[2] = ((scratch >> 16) & 0xff);
        !           939:                                sg->addr.addr[3] = ((scratch >> 24) & 0xff);
        !           940:                                xs->datalen += *(unsigned long *)sg->len.len = iovp->iov_len; 
        !           941:                                if(scsi_debug & SHOWSCATGATH)
        !           942:                                        printf("(0x%x@0x%x)"
        !           943:                                                        ,iovp->iov_len
        !           944:                                                        ,iovp->iov_base);
        !           945:                                sg++;
        !           946:                                iovp++;
        !           947:                                seg++;
        !           948:                                datalen--;
        !           949:                        }
        !           950:                }
        !           951:                else
        !           952:                {
        !           953:                        /***********************************************\
        !           954:                        * Set up the scatter gather block               *
        !           955:                        \***********************************************/
        !           956:                
        !           957:                        if(scsi_debug & SHOWSCATGATH)
        !           958:                                printf("%d @0x%x:- ",xs->datalen,xs->data);
        !           959:                        datalen         =       xs->datalen;
        !           960:                        thiskv          =       (int)xs->data;
        !           961:                        thisphys        =       KVTOPHYS(thiskv);
        !           962:                        templen         =       0;
        !           963:                
        !           964:                        while ((datalen) && (seg < UHA_NSEG))
        !           965:                        {
        !           966:                                bytes_this_seg  = 0;
        !           967:        
        !           968:                                /* put in the base address */
        !           969:                                sg->addr.addr[0] = (thisphys & 0xff);
        !           970:                                sg->addr.addr[1] = ((thisphys >> 8) & 0xff);
        !           971:                                sg->addr.addr[2] = ((thisphys >> 16) & 0xff);
        !           972:                                sg->addr.addr[3] = ((thisphys >> 24) & 0xff);
        !           973:                
        !           974:                                if(scsi_debug & SHOWSCATGATH)
        !           975:                                        printf("0x%x",thisphys);
        !           976:        
        !           977:                                /* do it at least once */
        !           978:                                nextphys = thisphys;    
        !           979:                                while ((datalen) && (thisphys == nextphys))
        !           980:                                /*********************************************\
        !           981:                                * This page is contiguous (physically) with   *
        !           982:                                * the the last, just extend the length        *
        !           983:                                \*********************************************/
        !           984:                                {
        !           985:                                        /* how far to the end of the page */
        !           986:                                        nextphys = (thisphys & (~(PAGESIZ - 1)))
        !           987:                                                                + PAGESIZ;
        !           988:                                        bytes_this_page = nextphys - thisphys;
        !           989:                                        /**** or the data ****/
        !           990:                                        bytes_this_page = min(bytes_this_page
        !           991:                                                                ,datalen);
        !           992:                                        bytes_this_seg  += bytes_this_page;
        !           993:                                        datalen         -= bytes_this_page;
        !           994:                
        !           995:                                        /* get more ready for the next page */
        !           996:                                        thiskv  = (thiskv & (~(PAGESIZ - 1)))
        !           997:                                                                + PAGESIZ;
        !           998:                                        if(datalen)
        !           999:                                                thisphys = KVTOPHYS(thiskv);
        !          1000:                                }
        !          1001:                                /********************************************\
        !          1002:                                * next page isn't contiguous, finish the seg *
        !          1003:                                \********************************************/
        !          1004:                                if(scsi_debug & SHOWSCATGATH)
        !          1005:                                        printf("(0x%x)",bytes_this_seg);
        !          1006:                                sg->len.len[0] = (bytes_this_seg & 0xff);
        !          1007:                                sg->len.len[1] = ((bytes_this_seg >> 8) & 0xff);
        !          1008:                                sg->len.len[2] = ((bytes_this_seg >> 16) & 0xff);
        !          1009:                                sg->len.len[3] = ((bytes_this_seg >> 24) & 0xff);
        !          1010:                                templen += bytes_this_seg;
        !          1011:                                sg++;
        !          1012:                                seg++;
        !          1013:                        }
        !          1014:                } /*end of iov/kv decision */
        !          1015:                mscp->datalen.len[0] = (templen & 0xff);
        !          1016:                mscp->datalen.len[1] = ((templen >> 8) & 0xff);
        !          1017:                mscp->datalen.len[2] = ((templen >> 16) & 0xff);
        !          1018:                mscp->datalen.len[3] = ((templen >> 24) & 0xff);
        !          1019:                mscp->sg_num = seg;
        !          1020: 
        !          1021:                if(scsi_debug & SHOWSCATGATH)
        !          1022:                        printf("\n");
        !          1023:                if (datalen)
        !          1024:                { /* there's still data, must have run out of segs! */
        !          1025:                        printf("uha_scsi_cmd%d: more than %d DMA segs\n",
        !          1026:                                unit,UHA_NSEG);
        !          1027:                        xs->error = XS_DRIVER_STUFFUP;
        !          1028:                        uha_free_mscp(unit,mscp,flags);
        !          1029:                        return(HAD_ERROR);
        !          1030:                }
        !          1031: 
        !          1032:        }
        !          1033:        else
        !          1034:        {       /* No data xfer, use non S/G values */
        !          1035:                mscp->data.addr[0] = 0x00;
        !          1036:                mscp->data.addr[1] = 0x00;
        !          1037:                mscp->data.addr[2] = 0x00;
        !          1038:                mscp->data.addr[3] = 0x00;
        !          1039:                mscp->datalen.len[0] = 0x00;
        !          1040:                mscp->datalen.len[1] = 0x00;
        !          1041:                mscp->datalen.len[2] = 0x00;
        !          1042:                mscp->datalen.len[3] = 0x00;
        !          1043:                mscp->xdir = 0x03;
        !          1044:                mscp->sgth = 0x00;
        !          1045:                mscp->sg_num = 0x00;    
        !          1046:        }
        !          1047: 
        !          1048:        /***********************************************\
        !          1049:        * Put the scsi command in the mscp and start it  *
        !          1050:        \***********************************************/
        !          1051:        bcopy(xs->cmd, mscp->cdb, xs->cmdlen); 
        !          1052: 
        !          1053:        /***********************************************\
        !          1054:        * Usually return SUCCESSFULLY QUEUED            *
        !          1055:        \***********************************************/
        !          1056:        if (!(flags & SCSI_NOMASK))
        !          1057:        {
        !          1058:                s = splbio();
        !          1059:                uha_send_mbox(unit,mscp);
        !          1060:                uha_add_timeout(mscp,xs->timeout);
        !          1061:                splx(s);
        !          1062:                if(scsi_debug & TRACEINTERRUPTS)
        !          1063:                        printf("cmd_sent ");
        !          1064:                return(SUCCESSFULLY_QUEUED);
        !          1065:        }
        !          1066:        /***********************************************\
        !          1067:        * If we can't use interrupts, poll on completion*
        !          1068:        \***********************************************/
        !          1069:        uha_send_mbox(unit,mscp);
        !          1070:        if(scsi_debug & TRACEINTERRUPTS)
        !          1071:                printf("cmd_wait ");
        !          1072:        do
        !          1073:        {
        !          1074:                if(uha_poll(unit,xs->timeout))
        !          1075:                {
        !          1076:                        if (!(xs->flags & SCSI_SILENT)) printf("cmd fail\n");
        !          1077:                        if(!(uha_abort(unit,mscp)))
        !          1078:                        {
        !          1079:                                printf("abort failed in wait\n");
        !          1080:                                uha_free_mscp(unit,mscp,flags);
        !          1081:                        }
        !          1082:                        xs->error = XS_DRIVER_STUFFUP;
        !          1083:                        splx(s);
        !          1084:                        return(HAD_ERROR);
        !          1085:                }
        !          1086:        } while (!(xs->flags & ITSDONE));/* something (?) else finished */
        !          1087:        splx(s);
        !          1088: scsi_debug = 0;uha_debug = 0;
        !          1089:        if(xs->error)
        !          1090:        {
        !          1091:                return(HAD_ERROR);
        !          1092:        }
        !          1093:        return(COMPLETE);
        !          1094: }
        !          1095: 
        !          1096: /*
        !          1097:  *                +----------+    +----------+    +----------+
        !          1098:  * uha_soonest--->|    later |--->|     later|--->|     later|--->0
        !          1099:  *                | [Delta]  |    | [Delta]  |    | [Delta]  |
        !          1100:  *           0<---|sooner    |<---|sooner    |<---|sooner    |<---uha_latest
        !          1101:  *                +----------+    +----------+    +----------+
        !          1102:  *
        !          1103:  *     uha_furtherest = sum(Delta[1..n])
        !          1104:  */
        !          1105: uha_add_timeout(mscp,time)
        !          1106: struct  mscp     *mscp;
        !          1107: int     time;
        !          1108: {
        !          1109:        int     timeprev;
        !          1110:        struct mscp *prev;
        !          1111:        int     s = splbio();
        !          1112: 
        !          1113:        if(prev = uha_latest) /* yes, an assign */
        !          1114:        {
        !          1115:                timeprev = uha_furtherest;
        !          1116:        }
        !          1117:        else
        !          1118:        {
        !          1119:                timeprev = 0;
        !          1120:        }
        !          1121:        while(prev && (timeprev > time)) 
        !          1122:        {
        !          1123:                timeprev -= prev->delta;
        !          1124:                prev = prev->sooner;
        !          1125:        }
        !          1126:        if(prev)
        !          1127:        {
        !          1128:                mscp->delta = time - timeprev;
        !          1129:                if( mscp->later = prev->later) /* yes an assign */
        !          1130:                {
        !          1131:                        mscp->later->sooner = mscp;
        !          1132:                        mscp->later->delta -= mscp->delta;
        !          1133:                }
        !          1134:                else
        !          1135:                {
        !          1136:                        uha_furtherest = time;
        !          1137:                        uha_latest = mscp;
        !          1138:                }
        !          1139:                mscp->sooner = prev;
        !          1140:                prev->later = mscp;
        !          1141:        }
        !          1142:        else
        !          1143:        {
        !          1144:                if( mscp->later = uha_soonest) /* yes, an assign*/
        !          1145:                {
        !          1146:                        mscp->later->sooner = mscp;
        !          1147:                        mscp->later->delta -= time;
        !          1148:                }
        !          1149:                else
        !          1150:                {
        !          1151:                        uha_furtherest = time;
        !          1152:                        uha_latest = mscp;
        !          1153:                }
        !          1154:                mscp->delta = time;
        !          1155:                mscp->sooner = (struct mscp *)0;
        !          1156:                uha_soonest = mscp;
        !          1157:        }
        !          1158:        splx(s);
        !          1159: }
        !          1160: 
        !          1161: uha_remove_timeout(mscp)
        !          1162: struct  mscp     *mscp;
        !          1163: {
        !          1164:        int     s = splbio();
        !          1165: 
        !          1166:        if(mscp->sooner)
        !          1167:        {
        !          1168:                mscp->sooner->later = mscp->later;
        !          1169:        }
        !          1170:        else
        !          1171:        {
        !          1172:                uha_soonest = mscp->later;
        !          1173:        }
        !          1174:        if(mscp->later)
        !          1175:        {
        !          1176:                mscp->later->sooner = mscp->sooner;
        !          1177:                mscp->later->delta += mscp->delta;
        !          1178:        }
        !          1179:        else
        !          1180:        {
        !          1181:                uha_latest = mscp->sooner;
        !          1182:                uha_furtherest -= mscp->delta;
        !          1183:        }
        !          1184:        mscp->sooner = mscp->later = (struct mscp *)0;
        !          1185:        splx(s);
        !          1186: }
        !          1187: 
        !          1188: 
        !          1189: extern int      hz;
        !          1190: #define ONETICK 500 /* milliseconds */
        !          1191: #define SLEEPTIME ((hz * 1000) / ONETICK)
        !          1192: uha_timeout(arg)
        !          1193: int     arg;
        !          1194: {
        !          1195:        struct  mscp  *mscp;
        !          1196:        int     unit;
        !          1197:        int     s       = splbio();
        !          1198:        unsigned int stat;
        !          1199:        int     port = uha_data[unit].baseport;
        !          1200: 
        !          1201:        while( mscp = uha_soonest )
        !          1202:        {
        !          1203:                if(mscp->delta <= ONETICK)
        !          1204:                /***********************************************\
        !          1205:                * It has timed out, we need to do some work     *
        !          1206:                \***********************************************/
        !          1207:                {
        !          1208:                        unit = mscp->xs->adapter;
        !          1209:                        printf("uha%d:%d device timed out\n",unit
        !          1210:                                        ,mscp->xs->targ);
        !          1211:                        if(uha_debug & UHA_SHOWMSCPS)
        !          1212:                                uha_print_active_mscp();
        !          1213: 
        !          1214:                        /***************************************\
        !          1215:                        * Unlink it from the queue              *
        !          1216:                        \***************************************/
        !          1217:                        uha_remove_timeout(mscp);
        !          1218: 
        !          1219:                        if((uha_abort(unit,mscp) !=1) || (mscp->flags = MSCP_ABORTED))
        !          1220:                        {
        !          1221:                                printf("AGAIN");
        !          1222:                                mscp->xs->retries = 0; /* I MEAN IT ! */
        !          1223:                                uha_done(unit,mscp,FAIL);
        !          1224:                        }
        !          1225:                        else    /* abort the operation that has timed out */
        !          1226:                        {
        !          1227:                                printf("\n");
        !          1228:                                uha_add_timeout(mscp,2000 + ONETICK);
        !          1229:                                mscp->flags = MSCP_ABORTED;
        !          1230:                        }
        !          1231:                }
        !          1232:                else
        !          1233:                /***********************************************\
        !          1234:                * It has not timed out, adjust and leave        *
        !          1235:                \***********************************************/
        !          1236:                {
        !          1237:                        mscp->delta -= ONETICK;
        !          1238:                        uha_furtherest -= ONETICK;
        !          1239:                        break;
        !          1240:                }
        !          1241:        }
        !          1242:        splx(s);
        !          1243:        timeout(uha_timeout,arg,SLEEPTIME);
        !          1244: }
        !          1245: 
        !          1246: uha_show_scsi_cmd(struct scsi_xfer *xs)
        !          1247: {
        !          1248:        u_char  *b = (u_char *)xs->cmd;
        !          1249:        int i = 0;
        !          1250:        if(!(xs->flags & SCSI_RESET))
        !          1251:        {
        !          1252:                printf("uha%d:%d:%d-"
        !          1253:                        ,xs->adapter
        !          1254:                        ,xs->targ
        !          1255:                        ,xs->lu);
        !          1256:                while(i < xs->cmdlen )
        !          1257:                {
        !          1258:                        if(i) printf(",");
        !          1259:                        printf("%x",b[i++]);
        !          1260:                }
        !          1261:                printf("-\n");
        !          1262:        }
        !          1263:        else
        !          1264:        {
        !          1265:                printf("uha%d:%d:%d-RESET-\n" 
        !          1266:                        ,xs->adapter 
        !          1267:                        ,xs->targ
        !          1268:                        ,xs->lu
        !          1269:                );
        !          1270:        }
        !          1271: }
        !          1272: uha_print_mscp(mscp)
        !          1273: struct  mscp *mscp;
        !          1274: {
        !          1275:        printf("mscp:%x op:%x cmdlen:%d senlen:%d\n"
        !          1276:                ,mscp
        !          1277:                ,mscp->opcode
        !          1278:                ,mscp->cdblen
        !          1279:                ,mscp->senselen);
        !          1280:        printf("        sg:%d sgnum:%x datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n"
        !          1281:                ,mscp->sgth
        !          1282:                ,mscp->sg_num
        !          1283:                ,mscp->datalen
        !          1284:                ,mscp->ha_status
        !          1285:                ,mscp->targ_status
        !          1286:                ,mscp->delta
        !          1287:                ,mscp->flags);
        !          1288:        uha_show_scsi_cmd(mscp->xs);
        !          1289: }
        !          1290: 
        !          1291: uha_print_active_mscp()
        !          1292: {
        !          1293:        struct  mscp *mscp;
        !          1294:        mscp = uha_soonest;
        !          1295: 
        !          1296:        while(mscp)
        !          1297:        {
        !          1298:                uha_print_mscp(mscp);
        !          1299:                mscp = mscp->later;
        !          1300:        }
        !          1301:        printf("Furtherest = %d\n",uha_furtherest);
        !          1302: }

unix.superglobalmegacorp.com

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