[BACK]Return to aha1742.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / eisa

Annotation of src/sys/arch/i386/eisa/aha1742.c, Revision 1.2

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

CVSweb <webmaster@jp.NetBSD.org>