Annotation of Net2/arch/i386/isa/aha1742.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Written by Julian Elischer ([email protected])
                      3:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
                      4:  *
                      5:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                      6:  * Mellon University, makes this software available to CMU to distribute
                      7:  * or use in any manner that they see fit as long as this message is kept with
                      8:  * the software. For this reason TFS also grants any other persons or
                      9:  * organisations permission to use or modify this software.
                     10:  *
                     11:  * TFS supplies this software to be publicly redistributed
                     12:  * on the understanding that TFS is not responsible for the correct
                     13:  * functioning of this software in any circumstances.
                     14:  *
                     15:  *
                     16:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
                     17:  * --------------------         -----   ----------------------
                     18:  * CURRENT PATCH LEVEL:         1       00098
                     19:  * --------------------         -----   ----------------------
                     20:  *
                     21:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
                     22:  * commenced: Sun Sep 27 18:14:01 PDT 1992
                     23:  */
                     24: 
                     25: #include <sys/types.h>
                     26: #include <ahb.h>
                     27: 
                     28: #include <sys/param.h>
                     29: #include <sys/systm.h>
                     30: #include <sys/errno.h>
                     31: #include <sys/ioctl.h>
                     32: #include <sys/buf.h>
                     33: #include <sys/proc.h>
                     34: #include <sys/user.h>
                     35: 
                     36: #ifdef  MACH    /* EITHER CMU OR OSF */
                     37: #include <i386/ipl.h>
                     38: #include <i386at/scsi.h>
                     39: #include <i386at/scsiconf.h>
                     40: 
                     41: #ifdef  OSF     /* OSF ONLY */
                     42: #include <sys/table.h>
                     43: #include <i386/handler.h>
                     44: #include <i386/dispatcher.h>
                     45: #include <i386/AT386/atbus.h>
                     46: 
                     47: #else   OSF     /* CMU ONLY */
                     48: #include <i386at/atbus.h>
                     49: #include <i386/pio.h>
                     50: #endif  OSF
                     51: #endif  MACH    /* end of MACH specific */
                     52: 
                     53: #ifdef  __386BSD__      /* 386BSD specific */
                     54: #define isa_dev isa_device
                     55: #define dev_unit id_unit
                     56: #define dev_addr id_iobase
                     57: 
                     58: #include <i386/include/pio.h>
                     59: #include <i386/isa/isa_device.h>
                     60: #include <scsi/scsi_all.h>
                     61: #include <scsi/scsiconf.h>
                     62: #endif  __386BSD__
                     63: 
                     64: /**/
                     65: 
                     66: #ifdef  __386BSD__
                     67: #ifdef DDB
                     68: int     Debugger();
                     69: #else 
                     70: #define Debugger() panic("should call debugger here (adaptec.c)")
                     71: #endif  /*DDB*/
                     72: #endif  __386BSD__
                     73: 
                     74: #ifdef  MACH
                     75: int     Debugger();
                     76: #endif  MACH
                     77: 
                     78: typedef unsigned long int physaddr;
                     79: 
                     80: #ifdef        MACH
                     81: extern physaddr kvtophys();
                     82: #define PHYSTOKV(x)   phystokv(x)
                     83: #define KVTOPHYS(x)   kvtophys(x)
                     84: #endif MACH
                     85: 
                     86: #ifdef        __386BSD__
                     87: #define PHYSTOKV(x)   (x | 0xFE000000)
                     88: #define KVTOPHYS(x)   vtophys(x)
                     89: #endif        __386BSD__
                     90: 
                     91: extern int delaycount;  /* from clock setup code */
                     92: #define        NUM_CONCURRENT  16      /* number of concurrent ops per board */
                     93: #define        AHB_NSEG        33      /* number of dma segments supported     */
                     94: #define FUDGE(X)       (X>>1)  /* our loops are slower than spinwait() */
                     95: /**/
                     96: /***********************************************************************\
                     97: * AHA1740 standard EISA Host ID regs  (Offset from slot base)          *
                     98: \***********************************************************************/
                     99: #define HID0           0xC80 /* 0,1: msb of ID2, 3-7: ID1      */
                    100: #define HID1           0xC81 /* 0-4: ID3, 4-7: LSB ID2         */
                    101: #define HID2           0xC82 /* product, 0=174[20] 1 = 1744    */
                    102: #define HID3           0xC83 /* firmware revision              */
                    103: 
                    104: #define CHAR1(B1,B2) (((B1>>2) & 0x1F) | '@')
                    105: #define CHAR2(B1,B2) (((B1<<3) & 0x18) | ((B2>>5) & 0x7)|'@')
                    106: #define CHAR3(B1,B2) ((B2 & 0x1F) | '@')
                    107: 
                    108: /* AHA1740 EISA board control registers (Offset from slot base) */
                    109: #define        EBCTRL          0xC84
                    110: #define  CDEN          0x01
                    111: /***********************************************************************\
                    112: * AHA1740 EISA board mode registers (Offset from slot base)            *
                    113: \***********************************************************************/
                    114: #define PORTADDR       0xCC0
                    115: #define         PORTADDR_ENHANCED      0x80
                    116: #define BIOSADDR       0xCC1
                    117: #define        INTDEF          0xCC2
                    118: #define        SCSIDEF         0xCC3
                    119: #define        BUSDEF          0xCC4
                    120: #define        RESV0           0xCC5
                    121: #define        RESV1           0xCC6
                    122: #define        RESV2           0xCC7
                    123: /**** bit definitions for INTDEF ****/
                    124: #define        INT9    0x00
                    125: #define        INT10   0x01
                    126: #define        INT11   0x02
                    127: #define        INT12   0x03
                    128: #define        INT14   0x05
                    129: #define        INT15   0x06
                    130: #define INTHIGH 0x08    /* int high=ACTIVE (else edge) */
                    131: #define        INTEN   0x10
                    132: /**** bit definitions for SCSIDEF ****/
                    133: #define        HSCSIID 0x0F    /* our SCSI ID */
                    134: #define        RSTPWR  0x10    /* reset scsi bus on power up or reset */
                    135: /**** bit definitions for BUSDEF ****/
                    136: #define        B0uS    0x00    /* give up bus immediatly */
                    137: #define        B4uS    0x01    /* delay 4uSec. */
                    138: #define        B8uS    0x02
                    139: /***********************************************************************\
                    140: * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base)   *
                    141: \***********************************************************************/
                    142: #define MBOXOUT0       0xCD0
                    143: #define MBOXOUT1       0xCD1
                    144: #define MBOXOUT2       0xCD2
                    145: #define MBOXOUT3       0xCD3
                    146: 
                    147: #define        ATTN            0xCD4
                    148: #define        G2CNTRL         0xCD5
                    149: #define        G2INTST         0xCD6
                    150: #define G2STAT         0xCD7
                    151: 
                    152: #define        MBOXIN0         0xCD8
                    153: #define        MBOXIN1         0xCD9
                    154: #define        MBOXIN2         0xCDA
                    155: #define        MBOXIN3         0xCDB
                    156: 
                    157: #define G2STAT2                0xCDC
                    158: 
                    159: /*******************************************************\
                    160: * Bit definitions for the 5 control/status registers   *
                    161: \*******************************************************/
                    162: #define        ATTN_TARGET             0x0F
                    163: #define        ATTN_OPCODE             0xF0
                    164: #define  OP_IMMED              0x10
                    165: #define          AHB_TARG_RESET        0x80
                    166: #define  OP_START_ECB          0x40
                    167: #define  OP_ABORT_ECB          0x50
                    168: 
                    169: #define        G2CNTRL_SET_HOST_READY  0x20
                    170: #define        G2CNTRL_CLEAR_EISA_INT  0x40
                    171: #define        G2CNTRL_HARD_RESET      0x80
                    172: 
                    173: #define        G2INTST_TARGET          0x0F
                    174: #define        G2INTST_INT_STAT        0xF0
                    175: #define         AHB_ECB_OK             0x10
                    176: #define         AHB_ECB_RECOVERED      0x50
                    177: #define         AHB_HW_ERR             0x70
                    178: #define         AHB_IMMED_OK           0xA0
                    179: #define         AHB_ECB_ERR            0xC0
                    180: #define         AHB_ASN                0xD0    /* for target mode */
                    181: #define         AHB_IMMED_ERR          0xE0
                    182: 
                    183: #define        G2STAT_BUSY             0x01
                    184: #define        G2STAT_INT_PEND         0x02
                    185: #define        G2STAT_MBOX_EMPTY       0x04
                    186: 
                    187: #define        G2STAT2_HOST_READY      0x01
                    188: /**/
                    189: 
                    190: struct ahb_dma_seg
                    191: {
                    192:        physaddr        addr;
                    193:        long            len;
                    194: };
                    195: 
                    196: struct ahb_ecb_status
                    197: {
                    198:        u_short status;
                    199: #       define ST_DON  0x0001
                    200: #       define ST_DU   0x0002
                    201: #       define ST_QF   0x0008
                    202: #       define ST_SC   0x0010
                    203: #       define ST_DO   0x0020
                    204: #       define ST_CH   0x0040
                    205: #       define ST_INT  0x0080
                    206: #       define ST_ASA  0x0100
                    207: #       define ST_SNS  0x0200
                    208: #       define ST_INI  0x0800
                    209: #       define ST_ME   0x1000
                    210: #       define ST_ECA  0x4000
                    211:        u_char  ha_status;
                    212: #       define HS_OK                   0x00
                    213: #       define HS_CMD_ABORTED_HOST     0x04
                    214: #       define HS_CMD_ABORTED_ADAPTER  0x05
                    215: #       define HS_TIMED_OUT            0x11
                    216: #       define HS_HARDWARE_ERR         0x20
                    217: #       define HS_SCSI_RESET_ADAPTER   0x22
                    218: #       define HS_SCSI_RESET_INCOMING  0x23
                    219:        u_char  targ_status;
                    220: #       define TS_OK                   0x00
                    221: #       define TS_CHECK_CONDITION      0x02
                    222: #       define TS_BUSY                 0x08
                    223:        u_long  resid_count;
                    224:        u_long  resid_addr;
                    225:        u_short addit_status;
                    226:        u_char  sense_len;
                    227:        u_char  unused[9];
                    228:        u_char  cdb[6];
                    229: };
                    230: 
                    231: /**/
                    232: 
                    233: struct ecb
                    234: {
                    235:        u_char  opcode;
                    236: #       define ECB_SCSI_OP     0x01
                    237:        u_char  :4;
                    238:        u_char  options:3;
                    239:        u_char  :1;
                    240:        short opt1;
                    241: #       define ECB_CNE 0x0001
                    242: #       define ECB_DI  0x0080
                    243: #       define ECB_SES 0x0400
                    244: #       define ECB_S_G 0x1000
                    245: #       define ECB_DSB 0x4000
                    246: #       define ECB_ARS 0x8000
                    247:        short opt2;
                    248: #       define ECB_LUN 0x0007
                    249: #       define ECB_TAG 0x0008
                    250: #       define ECB_TT  0x0030
                    251: #       define ECB_ND  0x0040
                    252: #       define ECB_DAT 0x0100
                    253: #       define ECB_DIR 0x0200
                    254: #       define ECB_ST  0x0400
                    255: #       define ECB_CHK 0x0800
                    256: #       define ECB_REC 0x4000
                    257: #       define ECB_NRB 0x8000
                    258:        u_short         unused1;
                    259:        physaddr        data;
                    260:        u_long          datalen;
                    261:        physaddr        status;
                    262:        physaddr        chain;
                    263:        short           unused2;
                    264:        short           unused3;
                    265:        physaddr        sense;
                    266:        u_char          senselen;
                    267:        u_char          cdblen;
                    268:        short           cksum;
                    269:        u_char          cdb[12];
                    270:        /*-----------------end of hardware supported fields----------------*/
                    271:        struct  ecb     *next;  /* in free list */
                    272:        struct  scsi_xfer *xs; /* the scsi_xfer for this cmd */
                    273:        long    int     delta;  /* difference from previous*/
                    274:        struct  ecb     *later,*sooner;
                    275:        int             flags;
                    276: #define ECB_FREE       0
                    277: #define ECB_ACTIVE     1
                    278: #define ECB_ABORTED    2
                    279: #define ECB_IMMED      4
                    280: #define ECB_IMMED_FAIL 8
                    281:        struct  ahb_dma_seg     ahb_dma[AHB_NSEG];
                    282:        struct  ahb_ecb_status  ecb_status;
                    283:        struct  scsi_sense_data ecb_sense;
                    284: };
                    285: 
                    286: struct ecb     *ahb_soonest    = (struct ecb *)0;
                    287: struct ecb     *ahb_latest     = (struct ecb *)0;
                    288: long   int     ahb_furtherest  = 0; /* longest time in the timeout queue */
                    289: /**/
                    290: 
                    291: struct ahb_data
                    292: {
                    293:        int     flags;
                    294: #define        AHB_INIT        0x01;
                    295:        int     baseport;
                    296:        struct  ecb ecbs[NUM_CONCURRENT];
                    297:        struct  ecb *free_ecb;
                    298:        int     our_id;                 /* our scsi id */
                    299:        int     vect;
                    300:        struct  ecb *immed_ecb;         /* an outstanding immediete command */
                    301: } ahb_data[NAHB];
                    302: 
                    303: int    ahbprobe();
                    304: int    ahb_attach();
                    305: int    ahbintr();
                    306: int    ahb_scsi_cmd();
                    307: int    ahb_timeout();
                    308: struct ecb *cheat;
                    309: void   ahbminphys();
                    310: long int ahb_adapter_info();
                    311: 
                    312: #ifdef  MACH
                    313: struct  isa_driver      ahbdriver = { ahbprobe, 0, ahb_attach, "ahb", 0, 0, 0};
                    314: int (*ahbintrs[])() = {ahbintr, 0};
                    315: #endif  MACH
                    316: 
                    317: #ifdef  __386BSD__
                    318: struct  isa_driver      ahbdriver = { ahbprobe, ahb_attach, "ahb"};
                    319: #endif  __386BSD__
                    320: 
                    321: #define        MAX_SLOTS       8
                    322: static ahb_slot = 0;   /* slot last board was found in */
                    323: static ahb_unit = 0;
                    324: int    ahb_debug = 0;
                    325: #define AHB_SHOWECBS 0x01
                    326: #define AHB_SHOWINTS 0x02
                    327: #define AHB_SHOWCMDS 0x04
                    328: #define AHB_SHOWMISC 0x08
                    329: #define FAIL   1
                    330: #define SUCCESS 0
                    331: #define PAGESIZ 4096
                    332: 
                    333: struct scsi_switch     ahb_switch = 
                    334: {
                    335:        ahb_scsi_cmd,
                    336:        ahbminphys,
                    337:        0,
                    338:        0,
                    339:        ahb_adapter_info,
                    340:        0,0,0
                    341: };
                    342: 
                    343: /**/
                    344: /***********************************************************************\
                    345: * Function to send a command out through a mailbox                     *
                    346: \***********************************************************************/
                    347: ahb_send_mbox( int             unit
                    348:                ,int            opcode
                    349:                ,int            target
                    350:                ,struct ecb     *ecb)
                    351: {
                    352:        int     port = ahb_data[unit].baseport;
                    353:        int     spincount = FUDGE(delaycount) * 1; /* 1ms should be enough */
                    354:        int     s = splbio();
                    355:        int     stport = port + G2STAT;
                    356: 
                    357:        while(      ((inb(stport) & (G2STAT_BUSY | G2STAT_MBOX_EMPTY))
                    358:                                        != (G2STAT_MBOX_EMPTY))
                    359:                && (spincount--));
                    360:        if(spincount == -1)
                    361:        {
                    362:                printf("ahb%d: board not responding\n",unit);
                    363:                Debugger();
                    364:        }
                    365: 
                    366:        outl(port + MBOXOUT0,KVTOPHYS(ecb));    /* don't know this will work */
                    367:        outb(port + ATTN, opcode|target);
                    368: 
                    369:        splx(s);
                    370: }
                    371: 
                    372: /***********************************************************************\
                    373: * Function to poll for command completion when in poll mode            *
                    374: \***********************************************************************/
                    375: ahb_poll(int unit ,int wait) /* in msec  */
                    376: {
                    377:        int     port = ahb_data[unit].baseport;
                    378:        int     spincount = FUDGE(delaycount) * wait; /* in msec */
                    379:        int     stport = port + G2STAT;
                    380: int    start = spincount;
                    381: 
                    382: retry:
                    383:        while( (spincount--) && (!(inb(stport) &  G2STAT_INT_PEND)));
                    384:        if(spincount == -1)
                    385:        {
                    386:                printf("ahb%d: board not responding\n",unit);
                    387:                return(EIO);
                    388:        }
                    389: if ((int)cheat != PHYSTOKV(inl(port + MBOXIN0)))
                    390: {
                    391:        printf("discarding %x ",inl(port + MBOXIN0));
                    392:        outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
                    393:        spinwait(50);
                    394:        goto retry;
                    395: }/* don't know this will work */
                    396:        ahbintr(unit);
                    397:        return(0);
                    398: }
                    399: /***********************************************************************\
                    400: * Function to  send an immediate type command to the adapter           *
                    401: \***********************************************************************/
                    402: ahb_send_immed(        int             unit
                    403:                ,int            target
                    404:                ,u_long         cmd)
                    405: {
                    406:        int     port = ahb_data[unit].baseport;
                    407:        int     spincount = FUDGE(delaycount) * 1; /* 1ms should be enough */
                    408:        int     s = splbio();
                    409:        int     stport = port + G2STAT;
                    410: 
                    411:        while(      ((inb(stport) & (G2STAT_BUSY | G2STAT_MBOX_EMPTY))
                    412:                                        != (G2STAT_MBOX_EMPTY))
                    413:                && (spincount--));
                    414:        if(spincount == -1)
                    415:        {
                    416:                printf("ahb%d: board not responding\n",unit);
                    417:                Debugger();
                    418:        }
                    419: 
                    420:        outl(port + MBOXOUT0,cmd);      /* don't know this will work */
                    421:        outb(port + G2CNTRL, G2CNTRL_SET_HOST_READY);
                    422:        outb(port + ATTN, OP_IMMED | target);
                    423:        splx(s);
                    424: }
                    425: 
                    426: /**/
                    427: 
                    428: /*******************************************************\
                    429: * Check  the slots looking for a board we recognise    *
                    430: * If we find one, note it's address (slot) and call    *
                    431: * the actual probe routine to check it out.            *
                    432: \*******************************************************/
                    433: ahbprobe(dev)
                    434: struct isa_dev *dev;
                    435: {
                    436:        int     port;
                    437:        u_char  byte1,byte2,byte3;
                    438:        ahb_slot++;
                    439:        while (ahb_slot<8)
                    440:        {
                    441:                port = 0x1000 * ahb_slot;
                    442:                byte1 = inb(port + HID0);
                    443:                byte2 = inb(port + HID1);
                    444:                byte3 = inb(port + HID2);
                    445:                if(byte1 == 0xff)
                    446:                {
                    447:                        ahb_slot++;
                    448:                        continue;
                    449:                }
                    450:                if ((CHAR1(byte1,byte2) == 'A')
                    451:                 && (CHAR2(byte1,byte2) == 'D')
                    452:                 && (CHAR3(byte1,byte2) == 'P')
                    453:                 && ((byte3 == 0 ) || (byte3 == 1)))
                    454:                {
                    455:                        dev->dev_addr = port;
                    456:                        return(ahbprobe1(dev) ? 0x1000 : 0);
                    457:                }
                    458:                ahb_slot++;
                    459:        }
                    460:        return(0);
                    461: }
                    462: /*******************************************************\
                    463: * Check if the device can be found at the port given    *
                    464: * and if so, set it up ready for further work           *
                    465: * as an argument, takes the isa_dev structure from      *
                    466: * autoconf.c                                            *
                    467: \*******************************************************/
                    468: ahbprobe1(dev)
                    469: struct isa_dev *dev;
                    470: {
                    471:        /***********************************************\
                    472:        * find unit and check we have that many defined *
                    473:        \***********************************************/
                    474:        int     unit = ahb_unit;
                    475: #if defined(OSF)
                    476:        static ihandler_t ahb_handler[NAHB];
                    477:        static ihandler_id_t *ahb_handler_id[NAHB];
                    478:        register ihandler_t *chp = &ahb_handler[unit];;
                    479: #endif /* defined(OSF) */
                    480: 
                    481:        dev->dev_unit = unit;
                    482:        ahb_data[unit].baseport = dev->dev_addr;
                    483:        if(unit >= NAHB) 
                    484:        {
                    485:                printf("ahb: unit number (%d) too high\n",unit);
                    486:                return(0);
                    487:        }
                    488:        /***********************************************\
                    489:        * Try initialise a unit at this location        *
                    490:        * sets up dma and bus speed, loads ahb_data[unit].vect*
                    491:        \***********************************************/
                    492:        if (ahb_init(unit) != 0)
                    493:        {
                    494:                return(0);
                    495:        }
                    496: 
                    497:        /***********************************************\
                    498:        * If it's there, put in it's interrupt vectors  *
                    499:        \***********************************************/
                    500: #ifdef MACH
                    501: #if defined(OSF)                               /* OSF */
                    502:        chp->ih_level = dev->dev_pic;
                    503:        chp->ih_handler = dev->dev_intr[0];
                    504:        chp->ih_resolver = i386_resolver;
                    505:        chp->ih_rdev = dev;
                    506:        chp->ih_stats.intr_type = INTR_DEVICE;
                    507:        chp->ih_stats.intr_cnt = 0;
                    508:        chp->ih_hparam[0].intparam = unit;
                    509:        if ((ahb_handler_id[unit] = handler_add(chp)) != NULL)
                    510:                handler_enable(ahb_handler_id[unit]);
                    511:        else
                    512:                panic("Unable to add ahb interrupt handler");
                    513: #else                                          /* CMU */
                    514:        dev->dev_pic = ahb_data[unit].vect;
                    515:        take_dev_irq(dev);
                    516: #endif /* !defined(OSF) */
                    517:        printf("port=%x spl=%d\n", dev->dev_addr, dev->dev_spl);
                    518: #endif MACH
                    519: #ifdef  __386BSD__                             /* 386BSD */
                    520:         dev->id_irq = (1 << ahb_data[unit].vect);
                    521:         dev->id_drq = -1; /* use EISA dma */
                    522:        printf("\n  **");
                    523: #endif  __386BSD__
                    524: 
                    525:        ahb_unit++;
                    526:        return(1);
                    527: }
                    528: 
                    529: /***********************************************\
                    530: * Attach all the sub-devices we can find       *
                    531: \***********************************************/
                    532: ahb_attach(dev)
                    533: struct isa_dev *dev;
                    534: {
                    535:        int     unit = dev->dev_unit;
                    536: 
                    537: 
                    538: #ifdef  __386BSD__
                    539:        printf("ahb%d: probing for scsi devices..\n", unit);
                    540: #endif  __386BSD__
                    541: 
                    542:        /***********************************************\
                    543:        * ask the adapter what subunits are present     *
                    544:        \***********************************************/
                    545:        scsi_attachdevs( unit, ahb_data[unit].our_id, &ahb_switch);
                    546: #if defined(OSF)
                    547:        ahb_attached[unit]=1;
                    548: #endif /* defined(OSF) */
                    549:        if(!unit) /* only one for all boards */
                    550:        {
                    551:                ahb_timeout(0);
                    552:        }
                    553:        return;
                    554: }
                    555: 
                    556: /***********************************************\
                    557: * Return some information to the caller about   *
                    558: * the adapter and it's capabilities             *
                    559: \***********************************************/
                    560: long int ahb_adapter_info(unit)
                    561: int    unit;
                    562: {
                    563:        return(2);      /* 2 outstanding requests at a time per device */
                    564: }
                    565: 
                    566: /***********************************************\
                    567: * Catch an interrupt from the adaptor          *
                    568: \***********************************************/
                    569: ahbintr(unit)
                    570: {
                    571:        struct ecb      *ecb;
                    572:        unsigned char   stat;
                    573:        register        i;
                    574:        u_char          ahbstat;
                    575:        int             target;
                    576:        long int        mboxval;
                    577: 
                    578:        int     port = ahb_data[unit].baseport;
                    579: 
                    580:        if(scsi_debug & PRINTROUTINES)
                    581:                printf("ahbintr ");
                    582: 
                    583: #if defined(OSF)
                    584:        if (!ahb_attached[unit])
                    585:        {
                    586:                return(1);
                    587:        }
                    588: #endif /* defined(OSF) */
                    589:        while(inb(port + G2STAT) & G2STAT_INT_PEND)
                    590:        {
                    591:                /***********************************************\
                    592:                * First get all the information and then        *
                    593:                * acknowlege the interrupt                      *
                    594:                \***********************************************/
                    595:                ahbstat = inb(port + G2INTST);
                    596:                target = ahbstat & G2INTST_TARGET;
                    597:                stat = ahbstat & G2INTST_INT_STAT;
                    598:                mboxval = inl(port + MBOXIN0);/* don't know this will work */
                    599:                outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
                    600:                if(scsi_debug & TRACEINTERRUPTS)
                    601:                        printf("status = 0x%x ",stat);
                    602:                /***********************************************\
                    603:                * Process the completed operation               *
                    604:                \***********************************************/
                    605:        
                    606:                if(stat == AHB_ECB_OK) /* common case is fast */
                    607:                {
                    608:                        ecb = (struct ecb *)PHYSTOKV(mboxval); 
                    609:                }
                    610:                else
                    611:                {
                    612:                        switch(stat)
                    613:                        {
                    614:                        case    AHB_IMMED_OK:
                    615:                                ecb = ahb_data[unit].immed_ecb;
                    616:                                ahb_data[unit].immed_ecb = 0;
                    617:                                break;
                    618:                        case    AHB_IMMED_ERR:
                    619:                                ecb = ahb_data[unit].immed_ecb;
                    620:                                ecb->flags |= ECB_IMMED_FAIL;
                    621:                                ahb_data[unit].immed_ecb = 0;
                    622:                                break;
                    623:                        case    AHB_ASN:        /* for target mode */
                    624:                                ecb = 0;
                    625:                                break;
                    626:                        case    AHB_HW_ERR:
                    627:                                ecb = 0;
                    628:                                break;
                    629:                        case    AHB_ECB_RECOVERED:
                    630:                                ecb = (struct ecb *)PHYSTOKV(mboxval); 
                    631:                                break;
                    632:                        case    AHB_ECB_ERR:
                    633:                                ecb = (struct ecb *)PHYSTOKV(mboxval); 
                    634:                                break;
                    635:                        default:
                    636:                                printf(" Unknown return from ahb%d(%x)\n",unit,ahbstat);
                    637:                                ecb=0;
                    638:                        }
                    639:                }
                    640:                if(ecb)
                    641:                {
                    642:                        if(ahb_debug & AHB_SHOWCMDS )
                    643:                        {
                    644:                                ahb_show_scsi_cmd(ecb->xs);
                    645:                        }
                    646:                        if((ahb_debug & AHB_SHOWECBS) && ecb)
                    647:                                printf("<int ecb(%x)>",ecb);
                    648:                        ahb_remove_timeout(ecb);
                    649:                        ahb_done(unit,ecb,((stat == AHB_ECB_OK)?SUCCESS:FAIL));
                    650:                }
                    651:        }
                    652:        return(1);
                    653: }
                    654: 
                    655: /***********************************************\
                    656: * We have a ecb which has been processed by the        *
                    657: * adaptor, now we look to see how the operation        *
                    658: * went.                                                *
                    659: \***********************************************/
                    660: ahb_done(unit,ecb,state)
                    661: int    unit,state;
                    662: struct ecb *ecb;
                    663: {
                    664:        struct  ahb_ecb_status  *stat = &ecb->ecb_status;
                    665:        struct  scsi_sense_data *s1,*s2;
                    666:        struct  scsi_xfer *xs = ecb->xs;
                    667: 
                    668:        if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS))
                    669:                printf("ahb_done ");
                    670:        /***********************************************\
                    671:        * Otherwise, put the results of the operation   *
                    672:        * into the xfer and call whoever started it     *
                    673:        \***********************************************/
                    674:        if(ecb->flags & ECB_IMMED)
                    675:        {
                    676:                if(ecb->flags & ECB_IMMED_FAIL)
                    677:                {
                    678:                        xs->error = XS_DRIVER_STUFFUP;
                    679:                }
                    680:                goto done;
                    681:        }
                    682:        if ( (state == SUCCESS) || (xs->flags & SCSI_ERR_OK))
                    683:        {               /* All went correctly  OR errors expected */
                    684:                xs->resid = 0;
                    685:                xs->error = 0;
                    686:        }
                    687:        else
                    688:        {
                    689: 
                    690:                s1 = &(ecb->ecb_sense);
                    691:                s2 = &(xs->sense);
                    692: 
                    693:                if(stat->ha_status)
                    694:                {
                    695:                        switch(stat->ha_status)
                    696:                        {
                    697:                        case    HS_SCSI_RESET_ADAPTER:
                    698:                                break;
                    699:                        case    HS_SCSI_RESET_INCOMING:
                    700:                                break;
                    701:                        case    HS_CMD_ABORTED_HOST:    /* No response */
                    702:                        case    HS_CMD_ABORTED_ADAPTER: /* No response */
                    703:                                break;
                    704:                        case    HS_TIMED_OUT:           /* No response */
                    705:                                if (ahb_debug & AHB_SHOWMISC)
                    706:                                {
                    707:                                        printf("timeout reported back\n");
                    708:                                }
                    709:                                xs->error = XS_TIMEOUT;
                    710:                                break;
                    711:                        default:        /* Other scsi protocol messes */
                    712:                                xs->error = XS_DRIVER_STUFFUP;
                    713:                                if (ahb_debug & AHB_SHOWMISC)
                    714:                                {
                    715:                                        printf("unexpected ha_status: %x\n",
                    716:                                                stat->ha_status);
                    717:                                }
                    718:                        }
                    719: 
                    720:                }
                    721:                else
                    722:                {
                    723:                        switch(stat->targ_status)
                    724:                        {
                    725:                        case TS_CHECK_CONDITION:
                    726:                                /* structure copy!!!!!*/
                    727:                                *s2=*s1;
                    728:                                xs->error = XS_SENSE;
                    729:                                break;
                    730:                        case TS_BUSY:
                    731:                                xs->error = XS_BUSY;
                    732:                                break;
                    733:                        default:
                    734:                                if (ahb_debug & AHB_SHOWMISC)
                    735:                                {
                    736:                                        printf("unexpected targ_status: %x\n",
                    737:                                                stat->targ_status);
                    738:                                }
                    739:                                xs->error = XS_DRIVER_STUFFUP;
                    740:                        }
                    741:                }
                    742:        }
                    743: done:  xs->flags |= ITSDONE;
                    744:        ahb_free_ecb(unit,ecb, xs->flags);
                    745:        if(xs->when_done)
                    746:                (*(xs->when_done))(xs->done_arg,xs->done_arg2);
                    747: }
                    748: 
                    749: /***********************************************\
                    750: * A ecb (and hence a mbx-out is put onto the   *
                    751: * free list.                                   *
                    752: \***********************************************/
                    753: ahb_free_ecb(unit,ecb, flags)
                    754: struct ecb *ecb;
                    755: {
                    756:        unsigned int opri;
                    757:        
                    758:        if(scsi_debug & PRINTROUTINES)
                    759:                printf("ecb%d(0x%x)> ",unit,flags);
                    760:        if (!(flags & SCSI_NOMASK)) 
                    761:                opri = splbio();
                    762: 
                    763:        ecb->next = ahb_data[unit].free_ecb;
                    764:        ahb_data[unit].free_ecb = ecb;
                    765:        ecb->flags = ECB_FREE;
                    766:        /***********************************************\
                    767:        * If there were none, wake abybody waiting for  *
                    768:        * one to come free, starting with queued entries*
                    769:        \***********************************************/
                    770:        if (!ecb->next) {
                    771:                wakeup(&ahb_data[unit].free_ecb);
                    772:        }
                    773:        if (!(flags & SCSI_NOMASK)) 
                    774:                splx(opri);
                    775: }
                    776: 
                    777: /***********************************************\
                    778: * Get a free ecb (and hence mbox-out entry)    *
                    779: \***********************************************/
                    780: struct ecb *
                    781: ahb_get_ecb(unit,flags)
                    782: {
                    783:        unsigned opri;
                    784:        struct ecb *rc;
                    785: 
                    786:        if(scsi_debug & PRINTROUTINES)
                    787:                printf("<ecb%d(0x%x) ",unit,flags);
                    788:        if (!(flags & SCSI_NOMASK)) 
                    789:                opri = splbio();
                    790:        /***********************************************\
                    791:        * If we can and have to, sleep waiting for one  *
                    792:        * to come free                                  *
                    793:        \***********************************************/
                    794:        while ((!(rc = ahb_data[unit].free_ecb)) && (!(flags & SCSI_NOSLEEP)))
                    795:        {
                    796:                sleep(&ahb_data[unit].free_ecb, PRIBIO);
                    797:        }
                    798:        if (rc) 
                    799:        {
                    800:                ahb_data[unit].free_ecb = rc->next;
                    801:                rc->flags = ECB_ACTIVE;
                    802:        }
                    803:        if (!(flags & SCSI_NOMASK)) 
                    804:                splx(opri);
                    805:        return(rc);
                    806: }
                    807:                
                    808: 
                    809: 
                    810: /***********************************************\
                    811: * Start the board, ready for normal operation  *
                    812: \***********************************************/
                    813: ahb_init(unit)
                    814: int    unit;
                    815: {
                    816:        int     port = ahb_data[unit].baseport;
                    817:        int     intdef;
                    818:        int     spincount = FUDGE(delaycount) * 1000; /* 1 sec enough? */
                    819:        int     i;
                    820:        int     stport = port + G2STAT;
                    821: #define        NO_NO 1
                    822: #ifdef NO_NO
                    823:        /***********************************************\
                    824:        * reset board, If it doesn't respond, assume    *
                    825:        * that it's not there.. good for the probe      *
                    826:        \***********************************************/
                    827:        outb(port + EBCTRL,CDEN);       /* enable full card */
                    828:        outb(port + PORTADDR,PORTADDR_ENHANCED);
                    829: 
                    830:        outb(port + G2CNTRL,G2CNTRL_HARD_RESET);
                    831:        spinwait(1);
                    832:        outb(port + G2CNTRL,0);
                    833:        spinwait(10);
                    834:        while(      ((inb(stport) & G2STAT_BUSY ))
                    835:                && (spincount--));
                    836:        if(spincount == -1)
                    837:        {
                    838:                if (ahb_debug & AHB_SHOWMISC)
                    839:                        printf("ahb_init: No answer from bt742a board\n");
                    840:                return(ENXIO);
                    841:        }
                    842:        i = inb(port + MBOXIN0) & 0xff;
                    843:        if(i)
                    844:        {
                    845:                printf("self test failed, val = 0x%x\n",i);
                    846:                return(EIO);
                    847:        }
                    848: #endif
                    849:        while( inb(stport) &  G2STAT_INT_PEND)
                    850:        {
                    851:                printf(".");
                    852:                outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
                    853:                spinwait(10);
                    854:        }
                    855:        outb(port + EBCTRL,CDEN);       /* enable full card */
                    856:        outb(port + PORTADDR,PORTADDR_ENHANCED);
                    857:        /***********************************************\
                    858:        * Assume we have a board at this stage          *
                    859:        * setup dma channel from jumpers and save int   *
                    860:        * level                                         *
                    861:        \***********************************************/
                    862: #ifdef __386BSD__
                    863:        printf("ahb%d reading board settings, ",unit);
                    864: #define        PRNT(x)
                    865: #else  __386BSD__
                    866:        printf("ahb%d:",unit);
                    867: #define        PRNT(x) printf(x)
                    868: #endif __386BSD__
                    869: 
                    870:        intdef = inb(port + INTDEF);
                    871:        switch(intdef & 0x07)
                    872:        {
                    873:        case    INT9:
                    874:                ahb_data[unit].vect = 9;
                    875:                PRNT("int=9 ");
                    876:                break;
                    877:        case    INT10:
                    878:                ahb_data[unit].vect = 10;
                    879:                PRNT("int=10 ");
                    880:                break;
                    881:        case    INT11:
                    882:                ahb_data[unit].vect = 11;
                    883:                PRNT("int=11 ");
                    884:                break;
                    885:        case    INT12:
                    886:                ahb_data[unit].vect = 12;
                    887:                PRNT("int=12 ");
                    888:                break;
                    889:        case    INT14:
                    890:                ahb_data[unit].vect = 14;
                    891:                PRNT("int=14 ");
                    892:                break;
                    893:        case    INT15:
                    894:                ahb_data[unit].vect = 15;
                    895:                PRNT("int=15 ");
                    896:                break;
                    897:        default:
                    898:                printf("illegal int setting\n");
                    899:                return(EIO);
                    900:        }
                    901:        outb(port + INTDEF ,(intdef | INTEN)); /* make sure we can interrupt */
                    902:        /* who are we on the scsi bus */
                    903:        ahb_data[unit].our_id = (inb(port + SCSIDEF) & HSCSIID);
                    904: 
                    905:        /***********************************************\
                    906:        * link up all our ECBs into a free list         *
                    907:        \***********************************************/
                    908:        for (i=0; i < NUM_CONCURRENT; i++)
                    909:        {
                    910:                ahb_data[unit].ecbs[i].next = ahb_data[unit].free_ecb;
                    911:                ahb_data[unit].free_ecb = &ahb_data[unit].ecbs[i];
                    912:                ahb_data[unit].free_ecb->flags = ECB_FREE;
                    913:        }
                    914: 
                    915:        /***********************************************\
                    916:        * Note that we are going and return (to probe)  *
                    917:        \***********************************************/
                    918:        ahb_data[unit].flags |= AHB_INIT;
                    919:        return( 0 );
                    920: }
                    921: 
                    922: 
                    923: #ifndef        min
                    924: #define min(x,y) (x < y ? x : y)
                    925: #endif min
                    926: 
                    927: 
                    928: void ahbminphys(bp)
                    929: struct buf *bp;
                    930: {
                    931: #ifdef MACH
                    932: #if    !defined(OSF)
                    933:        bp->b_flags |= B_NPAGES;                /* can support scat/gather */
                    934: #endif /* defined(OSF) */
                    935: #endif MACH
                    936:        if(bp->b_bcount > ((AHB_NSEG-1) * PAGESIZ))
                    937:        {
                    938:                bp->b_bcount = ((AHB_NSEG-1) * PAGESIZ);
                    939:        }
                    940: }
                    941:        
                    942: /***********************************************\
                    943: * start a scsi operation given the command and *
                    944: * the data address. Also needs the unit, target        *
                    945: * and lu                                       *
                    946: \***********************************************/
                    947: int    ahb_scsi_cmd(xs)
                    948: struct scsi_xfer *xs;
                    949: {
                    950:        struct  scsi_sense_data *s1,*s2;
                    951:        struct ecb *ecb;
                    952:        struct ahb_dma_seg *sg;
                    953:        int     seg;    /* scatter gather seg being worked on */
                    954:        int i   = 0;
                    955:        int rc  =  0;
                    956:        int     thiskv;
                    957:        physaddr        thisphys,nextphys;
                    958:        int     unit =xs->adapter;
                    959:        int     bytes_this_seg,bytes_this_page,datalen,flags;
                    960:        struct  iovec   *iovp;
                    961:        int     s;
                    962:        if(scsi_debug & PRINTROUTINES)
                    963:                printf("ahb_scsi_cmd ");
                    964:        /***********************************************\
                    965:        * get a ecb (mbox-out) to use. If the transfer  *
                    966:        * is from a buf (possibly from interrupt time)  *
                    967:        * then we can't allow it to sleep               *
                    968:        \***********************************************/
                    969:        flags = xs->flags;
                    970:        if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */
                    971:        if(flags & ITSDONE)
                    972:        {
                    973:                printf("Already done?");
                    974:                xs->flags &= ~ITSDONE;
                    975:        }
                    976:        if(!(flags & INUSE))
                    977:        {
                    978:                printf("Not in use?");
                    979:                xs->flags |= INUSE;
                    980:        }
                    981:        if (!(ecb = ahb_get_ecb(unit,flags)))
                    982:        {
                    983:                xs->error = XS_DRIVER_STUFFUP;
                    984:                return(TRY_AGAIN_LATER);
                    985:        }
                    986: 
                    987: cheat = ecb;
                    988:        if(ahb_debug & AHB_SHOWECBS)
                    989:                                printf("<start ecb(%x)>",ecb);
                    990:        if(scsi_debug & SHOWCOMMANDS)
                    991:        {
                    992:                ahb_show_scsi_cmd(xs);
                    993:        }
                    994:        ecb->xs = xs;
                    995:        /***********************************************\
                    996:        * If it's a reset, we need to do an 'immediate' *
                    997:        * command, and store it's ccb for later         *
                    998:        * if there is already an immediate waiting,     *
                    999:        * then WE must wait                             *
                   1000:        \***********************************************/
                   1001:        if(flags & SCSI_RESET)
                   1002:        {
                   1003:                ecb->flags |= ECB_IMMED;
                   1004:                if(ahb_data[unit].immed_ecb)
                   1005:                {
                   1006:                        return(TRY_AGAIN_LATER);
                   1007:                }
                   1008:                ahb_data[unit].immed_ecb = ecb;
                   1009:                if (!(flags & SCSI_NOMASK))
                   1010:                {
                   1011:                        s = splbio();
                   1012:                        ahb_send_immed(unit,xs->targ,AHB_TARG_RESET);
                   1013:                        ahb_add_timeout(ecb,xs->timeout);
                   1014:                        splx(s);
                   1015:                        return(SUCCESSFULLY_QUEUED);
                   1016:                }
                   1017:                else
                   1018:                {
                   1019:                        ahb_send_immed(unit,xs->targ,AHB_TARG_RESET);
                   1020:                        /***********************************************\
                   1021:                        * If we can't use interrupts, poll on completion*
                   1022:                        \***********************************************/
                   1023:                        if(scsi_debug & TRACEINTERRUPTS)
                   1024:                                printf("wait ");
                   1025:                        if( ahb_poll(unit,xs->timeout))
                   1026:                        {
                   1027:                                ahb_free_ecb(unit,ecb,flags);
                   1028:                                xs->error = XS_TIMEOUT;
                   1029:                                return(HAD_ERROR);
                   1030:                        }
                   1031:                        return(COMPLETE);
                   1032:                }
                   1033:        }       
                   1034:        /***********************************************\
                   1035:        * Put all the arguments for the xfer in the ecb *
                   1036:        \***********************************************/
                   1037:        ecb->opcode = ECB_SCSI_OP;
                   1038:        ecb->opt1 = ECB_SES|ECB_DSB|ECB_ARS;
                   1039:        if(xs->datalen)
                   1040:        {
                   1041:                ecb->opt1 |= ECB_S_G;
                   1042:        }
                   1043:        ecb->opt2               =       xs->lu | ECB_NRB;
                   1044:        ecb->cdblen             =       xs->cmdlen;
                   1045:        ecb->sense              =       KVTOPHYS(&(ecb->ecb_sense));
                   1046:        ecb->senselen           =       sizeof(ecb->ecb_sense);
                   1047:        ecb->status             =       KVTOPHYS(&(ecb->ecb_status));
                   1048: 
                   1049:        if(xs->datalen)
                   1050:        { /* should use S/G only if not zero length */
                   1051:                ecb->data       =       KVTOPHYS(ecb->ahb_dma);
                   1052:                sg              =       ecb->ahb_dma ;
                   1053:                seg             =       0;
                   1054:                if(flags & SCSI_DATA_UIO)
                   1055:                {
                   1056:                        iovp = ((struct uio *)xs->data)->uio_iov;
                   1057:                        datalen = ((struct uio *)xs->data)->uio_iovcnt;
                   1058:                        xs->datalen = 0;
                   1059:                        while ((datalen) && (seg < AHB_NSEG))
                   1060:                        {
                   1061:                                sg->addr = (physaddr)iovp->iov_base;
                   1062:                                xs->datalen += sg->len = iovp->iov_len; 
                   1063:                                if(scsi_debug & SHOWSCATGATH)
                   1064:                                        printf("(0x%x@0x%x)"
                   1065:                                                        ,iovp->iov_len
                   1066:                                                        ,iovp->iov_base);
                   1067:                                sg++;
                   1068:                                iovp++;
                   1069:                                seg++;
                   1070:                                datalen--;
                   1071:                        }
                   1072:                }
                   1073:                else
                   1074:                {
                   1075:                        /***********************************************\
                   1076:                        * Set up the scatter gather block               *
                   1077:                        \***********************************************/
                   1078:                
                   1079:                        if(scsi_debug & SHOWSCATGATH)
                   1080:                                printf("%d @0x%x:- ",xs->datalen,xs->data);
                   1081:                        datalen         =       xs->datalen;
                   1082:                        thiskv          =       (int)xs->data;
                   1083:                        thisphys        =       KVTOPHYS(thiskv);
                   1084:                
                   1085:                        while ((datalen) && (seg < AHB_NSEG))
                   1086:                        {
                   1087:                                bytes_this_seg  = 0;
                   1088:        
                   1089:                                /* put in the base address */
                   1090:                                sg->addr = thisphys;
                   1091:                
                   1092:                                if(scsi_debug & SHOWSCATGATH)
                   1093:                                        printf("0x%x",thisphys);
                   1094:        
                   1095:                                /* do it at least once */
                   1096:                                nextphys = thisphys;    
                   1097:                                while ((datalen) && (thisphys == nextphys))
                   1098:                                /*********************************************\
                   1099:                                * This page is contiguous (physically) with   *
                   1100:                                * the the last, just extend the length        *
                   1101:                                \*********************************************/
                   1102:                                {
                   1103:                                        /* how far to the end of the page */
                   1104:                                        nextphys= (thisphys & (~(PAGESIZ - 1)))
                   1105:                                                                + PAGESIZ;
                   1106:                                        bytes_this_page = nextphys - thisphys;
                   1107:                                        /**** or the data ****/
                   1108:                                        bytes_this_page = min(bytes_this_page
                   1109:                                                                ,datalen);
                   1110:                                        bytes_this_seg  += bytes_this_page;
                   1111:                                        datalen         -= bytes_this_page;
                   1112:                
                   1113:                                        /* get more ready for the next page */
                   1114:                                        thiskv  = (thiskv & (~(PAGESIZ - 1)))
                   1115:                                                                + PAGESIZ;
                   1116:                                        if(datalen)
                   1117:                                                thisphys = KVTOPHYS(thiskv);
                   1118:                                }
                   1119:                                /********************************************\
                   1120:                                * next page isn't contiguous, finish the seg *
                   1121:                                \********************************************/
                   1122:                                if(scsi_debug & SHOWSCATGATH)
                   1123:                                        printf("(0x%x)",bytes_this_seg);
                   1124:                                sg->len = bytes_this_seg;       
                   1125:                                sg++;
                   1126:                                seg++;
                   1127:                        }
                   1128:                } /*end of iov/kv decision */
                   1129:                ecb->datalen = seg * sizeof(struct ahb_dma_seg);
                   1130:                if(scsi_debug & SHOWSCATGATH)
                   1131:                        printf("\n");
                   1132:                if (datalen)
                   1133:                { /* there's still data, must have run out of segs! */
                   1134:                        printf("ahb_scsi_cmd%d: more than %d DMA segs\n",
                   1135:                                unit,AHB_NSEG);
                   1136:                        xs->error = XS_DRIVER_STUFFUP;
                   1137:                        ahb_free_ecb(unit,ecb,flags);
                   1138:                        return(HAD_ERROR);
                   1139:                }
                   1140: 
                   1141:        }
                   1142:        else
                   1143:        {       /* No data xfer, use non S/G values */
                   1144:                ecb->data = (physaddr)0;
                   1145:                ecb->datalen = 0;
                   1146:        }
                   1147:        ecb->chain = (physaddr)0;
                   1148:        /***********************************************\
                   1149:        * Put the scsi command in the ecb and start it  *
                   1150:        \***********************************************/
                   1151:        bcopy(xs->cmd, ecb->cdb, xs->cmdlen);
                   1152:        /***********************************************\
                   1153:        * Usually return SUCCESSFULLY QUEUED            *
                   1154:        \***********************************************/
                   1155:        if (!(flags & SCSI_NOMASK))
                   1156:        {
                   1157:                s = splbio();
                   1158:                ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb);
                   1159:                ahb_add_timeout(ecb,xs->timeout);
                   1160:                splx(s);
                   1161:                if(scsi_debug & TRACEINTERRUPTS)
                   1162:                        printf("cmd_sent ");
                   1163:                return(SUCCESSFULLY_QUEUED);
                   1164:        }
                   1165:        /***********************************************\
                   1166:        * If we can't use interrupts, poll on completion*
                   1167:        \***********************************************/
                   1168:        ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb);
                   1169:        if(scsi_debug & TRACEINTERRUPTS)
                   1170:                printf("cmd_wait ");
                   1171:        do
                   1172:        {
                   1173:                if(ahb_poll(unit,xs->timeout))
                   1174:                {
                   1175:                        if (!(xs->flags & SCSI_SILENT)) printf("cmd fail\n");
                   1176:                        ahb_send_mbox(unit,OP_ABORT_ECB,xs->targ,ecb);
                   1177:                        if(ahb_poll(unit,2000))
                   1178:                        {
                   1179:                                printf("abort failed in wait\n");
                   1180:                                ahb_free_ecb(unit,ecb,flags);
                   1181:                        }
                   1182:                        xs->error = XS_DRIVER_STUFFUP;
                   1183:                        splx(s);
                   1184:                        return(HAD_ERROR);
                   1185:                }
                   1186:        } while (!(xs->flags & ITSDONE));/* something (?) else finished */
                   1187:        splx(s);
                   1188: scsi_debug = 0;ahb_debug = 0;
                   1189:        if(xs->error)
                   1190:        {
                   1191:                return(HAD_ERROR);
                   1192:        }
                   1193:        return(COMPLETE);
                   1194: }
                   1195: 
                   1196: /*
                   1197:  *                +----------+    +----------+    +----------+
                   1198:  * ahb_soonest--->|    later |--->|     later|--->|     later|--->0
                   1199:  *                | [Delta]  |    | [Delta]  |    | [Delta]  |
                   1200:  *           0<---|sooner    |<---|sooner    |<---|sooner    |<---ahb_latest
                   1201:  *                +----------+    +----------+    +----------+
                   1202:  *
                   1203:  *     ahb_furtherest = sum(Delta[1..n])
                   1204:  */
                   1205: ahb_add_timeout(ecb,time)
                   1206: struct ecb     *ecb;
                   1207: int    time;
                   1208: {
                   1209:        int     timeprev;
                   1210:        struct ecb *prev;
                   1211:        int     s = splbio();
                   1212: 
                   1213:        if(prev = ahb_latest) /* yes, an assign */
                   1214:        {
                   1215:                timeprev = ahb_furtherest;
                   1216:        }
                   1217:        else
                   1218:        {
                   1219:                timeprev = 0;
                   1220:        }
                   1221:        while(prev && (timeprev > time)) 
                   1222:        {
                   1223:                timeprev -= prev->delta;
                   1224:                prev = prev->sooner;
                   1225:        }
                   1226:        if(prev)
                   1227:        {
                   1228:                ecb->delta = time - timeprev;
                   1229:                if( ecb->later = prev->later) /* yes an assign */
                   1230:                {
                   1231:                        ecb->later->sooner = ecb;
                   1232:                        ecb->later->delta -= ecb->delta;
                   1233:                }
                   1234:                else
                   1235:                {
                   1236:                        ahb_furtherest = time;
                   1237:                        ahb_latest = ecb;
                   1238:                }
                   1239:                ecb->sooner = prev;
                   1240:                prev->later = ecb;
                   1241:        }
                   1242:        else
                   1243:        {
                   1244:                if( ecb->later = ahb_soonest) /* yes, an assign*/
                   1245:                {
                   1246:                        ecb->later->sooner = ecb;
                   1247:                        ecb->later->delta -= time;
                   1248:                }
                   1249:                else
                   1250:                {
                   1251:                        ahb_furtherest = time;
                   1252:                        ahb_latest = ecb;
                   1253:                }
                   1254:                ecb->delta = time;
                   1255:                ecb->sooner = (struct ecb *)0;
                   1256:                ahb_soonest = ecb;
                   1257:        }
                   1258:        splx(s);
                   1259: }
                   1260: 
                   1261: ahb_remove_timeout(ecb)
                   1262: struct ecb     *ecb;
                   1263: {
                   1264:        int     s = splbio();
                   1265: 
                   1266:        if(ecb->sooner)
                   1267:        {
                   1268:                ecb->sooner->later = ecb->later;
                   1269:        }
                   1270:        else
                   1271:        {
                   1272:                ahb_soonest = ecb->later;
                   1273:        }
                   1274:        if(ecb->later)
                   1275:        {
                   1276:                ecb->later->sooner = ecb->sooner;
                   1277:                ecb->later->delta += ecb->delta;
                   1278:        }
                   1279:        else
                   1280:        {
                   1281:                ahb_latest = ecb->sooner;
                   1282:                ahb_furtherest -= ecb->delta;
                   1283:        }
                   1284:        ecb->sooner = ecb->later = (struct ecb *)0;
                   1285:        splx(s);
                   1286: }
                   1287: 
                   1288: 
                   1289: extern int     hz;
                   1290: #define ONETICK 500 /* milliseconds */
                   1291: #define SLEEPTIME ((hz * 1000) / ONETICK)
                   1292: ahb_timeout(arg)
                   1293: int    arg;
                   1294: {
                   1295:        struct  ecb  *ecb;
                   1296:        int     unit;
                   1297:        int     s       = splbio();
                   1298: 
                   1299:        while( ecb = ahb_soonest )
                   1300:        {
                   1301:                if(ecb->delta <= ONETICK)
                   1302:                /***********************************************\
                   1303:                * It has timed out, we need to do some work     *
                   1304:                \***********************************************/
                   1305:                {
                   1306:                        unit = ecb->xs->adapter;
                   1307:                        printf("ahb%d:%d device timed out\n",unit
                   1308:                                        ,ecb->xs->targ);
                   1309:                        if(ahb_debug & AHB_SHOWECBS)
                   1310:                                ahb_print_active_ecb();
                   1311: 
                   1312:                        /***************************************\
                   1313:                        * Unlink it from the queue              *
                   1314:                        \***************************************/
                   1315:                        ahb_remove_timeout(ecb);
                   1316: 
                   1317:                        /***************************************\
                   1318:                        * If it's immediate, don't try abort it *
                   1319:                        \***************************************/
                   1320:                        if(ecb->flags & ECB_IMMED)
                   1321:                        {
                   1322:                                ecb->xs->retries = 0; /* I MEAN IT ! */
                   1323:                                ecb->flags |= ECB_IMMED_FAIL;
                   1324:                                 ahb_done(unit,ecb,FAIL);
                   1325:                                continue;
                   1326:                        }
                   1327:                        /***************************************\
                   1328:                        * If it has been through before, then   *
                   1329:                        * a previous abort has failed, don't    *
                   1330:                        * try abort again                       *
                   1331:                        \***************************************/
                   1332:                        if(ecb->flags == ECB_ABORTED) /* abort timed out */
                   1333:                        {
                   1334:                                printf("AGAIN");
                   1335:                                ecb->xs->retries = 0; /* I MEAN IT ! */
                   1336:                                ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST;
                   1337:                                ahb_done(unit,ecb,FAIL);
                   1338:                        }
                   1339:                        else    /* abort the operation that has timed out */
                   1340:                        {
                   1341:                                printf("\n");
                   1342:                                ahb_send_mbox(unit,OP_ABORT_ECB,ecb->xs->targ,ecb);
                   1343:                                        /* 2 secs for the abort */
                   1344:                                ahb_add_timeout(ecb,2000 + ONETICK);
                   1345:                                ecb->flags = ECB_ABORTED;
                   1346:                        }
                   1347:                }
                   1348:                else
                   1349:                /***********************************************\
                   1350:                * It has not timed out, adjust and leave        *
                   1351:                \***********************************************/
                   1352:                {
                   1353:                        ecb->delta -= ONETICK;
                   1354:                        ahb_furtherest -= ONETICK;
                   1355:                        break;
                   1356:                }
                   1357:        }
                   1358:        splx(s);
                   1359:        timeout(ahb_timeout,arg,SLEEPTIME);
                   1360: }
                   1361: 
                   1362: ahb_show_scsi_cmd(struct scsi_xfer *xs)
                   1363: {
                   1364:        u_char  *b = (u_char *)xs->cmd;
                   1365:        int i = 0;
                   1366:        if(!(xs->flags & SCSI_RESET))
                   1367:        {
                   1368:                printf("ahb%d:%d:%d-"
                   1369:                        ,xs->adapter
                   1370:                        ,xs->targ
                   1371:                        ,xs->lu);
                   1372:                while(i < xs->cmdlen )
                   1373:                {
                   1374:                        if(i) printf(",");
                   1375:                        printf("%x",b[i++]);
                   1376:                }
                   1377:                printf("-\n");
                   1378:        }
                   1379:        else
                   1380:        {
                   1381:                printf("ahb%d:%d:%d-RESET-\n" 
                   1382:                        ,xs->adapter 
                   1383:                        ,xs->targ
                   1384:                        ,xs->lu
                   1385:                );
                   1386:        }
                   1387: }
                   1388: ahb_print_ecb(ecb)
                   1389: struct ecb *ecb;
                   1390: {
                   1391:        printf("ecb:%x op:%x cmdlen:%d senlen:%d\n"
                   1392:                ,ecb
                   1393:                ,ecb->opcode
                   1394:                ,ecb->cdblen
                   1395:                ,ecb->senselen);
                   1396:        printf("        datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n"
                   1397:                ,ecb->datalen
                   1398:                ,ecb->ecb_status.ha_status
                   1399:                ,ecb->ecb_status.targ_status
                   1400:                ,ecb->delta
                   1401:                ,ecb->flags);
                   1402:        ahb_show_scsi_cmd(ecb->xs);
                   1403: }
                   1404: 
                   1405: ahb_print_active_ecb()
                   1406: {
                   1407:        struct  ecb *ecb;
                   1408:        ecb = ahb_soonest;
                   1409: 
                   1410:        while(ecb)
                   1411:        {
                   1412:                ahb_print_ecb(ecb);
                   1413:                ecb = ecb->later;
                   1414:        }
                   1415:        printf("Furtherest = %d\n",ahb_furtherest);
                   1416: }

unix.superglobalmegacorp.com

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