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

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

unix.superglobalmegacorp.com

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