[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.1

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__
        !           540:        printf(" probing for scsi devices**\n");
        !           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: #ifdef  __386BSD__
        !           555:        printf("ahb%d",unit);
        !           556: #endif  __386BSD__
        !           557:        return;
        !           558: }
        !           559:
        !           560: /***********************************************\
        !           561: * Return some information to the caller about   *
        !           562: * the adapter and it's capabilities             *
        !           563: \***********************************************/
        !           564: long int ahb_adapter_info(unit)
        !           565: int    unit;
        !           566: {
        !           567:        return(2);      /* 2 outstanding requests at a time per device */
        !           568: }
        !           569:
        !           570: /***********************************************\
        !           571: * Catch an interrupt from the adaptor          *
        !           572: \***********************************************/
        !           573: ahbintr(unit)
        !           574: {
        !           575:        struct ecb      *ecb;
        !           576:        unsigned char   stat;
        !           577:        register        i;
        !           578:        u_char          ahbstat;
        !           579:        int             target;
        !           580:        long int        mboxval;
        !           581:
        !           582:        int     port = ahb_data[unit].baseport;
        !           583:
        !           584:        if(scsi_debug & PRINTROUTINES)
        !           585:                printf("ahbintr ");
        !           586:
        !           587: #if defined(OSF)
        !           588:        if (!ahb_attached[unit])
        !           589:        {
        !           590:                return(1);
        !           591:        }
        !           592: #endif /* defined(OSF) */
        !           593:        while(inb(port + G2STAT) & G2STAT_INT_PEND)
        !           594:        {
        !           595:                /***********************************************\
        !           596:                * First get all the information and then        *
        !           597:                * acknowlege the interrupt                      *
        !           598:                \***********************************************/
        !           599:                ahbstat = inb(port + G2INTST);
        !           600:                target = ahbstat & G2INTST_TARGET;
        !           601:                stat = ahbstat & G2INTST_INT_STAT;
        !           602:                mboxval = inl(port + MBOXIN0);/* don't know this will work */
        !           603:                outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
        !           604:                if(scsi_debug & TRACEINTERRUPTS)
        !           605:                        printf("status = 0x%x ",stat);
        !           606:                /***********************************************\
        !           607:                * Process the completed operation               *
        !           608:                \***********************************************/
        !           609:
        !           610:                if(stat == AHB_ECB_OK) /* common case is fast */
        !           611:                {
        !           612:                        ecb = (struct ecb *)PHYSTOKV(mboxval);
        !           613:                }
        !           614:                else
        !           615:                {
        !           616:                        switch(stat)
        !           617:                        {
        !           618:                        case    AHB_IMMED_OK:
        !           619:                                ecb = ahb_data[unit].immed_ecb;
        !           620:                                ahb_data[unit].immed_ecb = 0;
        !           621:                                break;
        !           622:                        case    AHB_IMMED_ERR:
        !           623:                                ecb = ahb_data[unit].immed_ecb;
        !           624:                                ecb->flags |= ECB_IMMED_FAIL;
        !           625:                                ahb_data[unit].immed_ecb = 0;
        !           626:                                break;
        !           627:                        case    AHB_ASN:        /* for target mode */
        !           628:                                ecb = 0;
        !           629:                                break;
        !           630:                        case    AHB_HW_ERR:
        !           631:                                ecb = 0;
        !           632:                                break;
        !           633:                        case    AHB_ECB_RECOVERED:
        !           634:                                ecb = (struct ecb *)PHYSTOKV(mboxval);
        !           635:                                break;
        !           636:                        case    AHB_ECB_ERR:
        !           637:                                ecb = (struct ecb *)PHYSTOKV(mboxval);
        !           638:                                break;
        !           639:                        default:
        !           640:                                printf(" Unknown return from ahb%d(%x)\n",unit,ahbstat);
        !           641:                                ecb=0;
        !           642:                        }
        !           643:                }
        !           644:                if(ecb)
        !           645:                {
        !           646:                        if(ahb_debug & AHB_SHOWCMDS )
        !           647:                        {
        !           648:                                ahb_show_scsi_cmd(ecb->xs);
        !           649:                        }
        !           650:                        if((ahb_debug & AHB_SHOWECBS) && ecb)
        !           651:                                printf("<int ecb(%x)>",ecb);
        !           652:                        ahb_remove_timeout(ecb);
        !           653:                        ahb_done(unit,ecb,((stat == AHB_ECB_OK)?SUCCESS:FAIL));
        !           654:                }
        !           655:        }
        !           656:        return(1);
        !           657: }
        !           658:
        !           659: /***********************************************\
        !           660: * We have a ecb which has been processed by the        *
        !           661: * adaptor, now we look to see how the operation        *
        !           662: * went.                                                *
        !           663: \***********************************************/
        !           664: ahb_done(unit,ecb,state)
        !           665: int    unit,state;
        !           666: struct ecb *ecb;
        !           667: {
        !           668:        struct  ahb_ecb_status  *stat = &ecb->ecb_status;
        !           669:        struct  scsi_sense_data *s1,*s2;
        !           670:        struct  scsi_xfer *xs = ecb->xs;
        !           671:
        !           672:        if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS))
        !           673:                printf("ahb_done ");
        !           674:        /***********************************************\
        !           675:        * Otherwise, put the results of the operation   *
        !           676:        * into the xfer and call whoever started it     *
        !           677:        \***********************************************/
        !           678:        if(ecb->flags & ECB_IMMED)
        !           679:        {
        !           680:                if(ecb->flags & ECB_IMMED_FAIL)
        !           681:                {
        !           682:                        xs->error = XS_DRIVER_STUFFUP;
        !           683:                }
        !           684:                goto done;
        !           685:        }
        !           686:        if ( (state == SUCCESS) || (xs->flags & SCSI_ERR_OK))
        !           687:        {               /* All went correctly  OR errors expected */
        !           688:                xs->resid = 0;
        !           689:                xs->error = 0;
        !           690:        }
        !           691:        else
        !           692:        {
        !           693:
        !           694:                s1 = &(ecb->ecb_sense);
        !           695:                s2 = &(xs->sense);
        !           696:
        !           697:                if(stat->ha_status)
        !           698:                {
        !           699:                        switch(stat->ha_status)
        !           700:                        {
        !           701:                        case    HS_SCSI_RESET_ADAPTER:
        !           702:                                break;
        !           703:                        case    HS_SCSI_RESET_INCOMING:
        !           704:                                break;
        !           705:                        case    HS_CMD_ABORTED_HOST:    /* No response */
        !           706:                        case    HS_CMD_ABORTED_ADAPTER: /* No response */
        !           707:                                break;
        !           708:                        case    HS_TIMED_OUT:           /* No response */
        !           709:                                if (ahb_debug & AHB_SHOWMISC)
        !           710:                                {
        !           711:                                        printf("timeout reported back\n");
        !           712:                                }
        !           713:                                xs->error = XS_TIMEOUT;
        !           714:                                break;
        !           715:                        default:        /* Other scsi protocol messes */
        !           716:                                xs->error = XS_DRIVER_STUFFUP;
        !           717:                                if (ahb_debug & AHB_SHOWMISC)
        !           718:                                {
        !           719:                                        printf("unexpected ha_status: %x\n",
        !           720:                                                stat->ha_status);
        !           721:                                }
        !           722:                        }
        !           723:
        !           724:                }
        !           725:                else
        !           726:                {
        !           727:                        switch(stat->targ_status)
        !           728:                        {
        !           729:                        case TS_CHECK_CONDITION:
        !           730:                                /* structure copy!!!!!*/
        !           731:                                *s2=*s1;
        !           732:                                xs->error = XS_SENSE;
        !           733:                                break;
        !           734:                        case TS_BUSY:
        !           735:                                xs->error = XS_BUSY;
        !           736:                                break;
        !           737:                        default:
        !           738:                                if (ahb_debug & AHB_SHOWMISC)
        !           739:                                {
        !           740:                                        printf("unexpected targ_status: %x\n",
        !           741:                                                stat->targ_status);
        !           742:                                }
        !           743:                                xs->error = XS_DRIVER_STUFFUP;
        !           744:                        }
        !           745:                }
        !           746:        }
        !           747: done:  xs->flags |= ITSDONE;
        !           748:        ahb_free_ecb(unit,ecb, xs->flags);
        !           749:        if(xs->when_done)
        !           750:                (*(xs->when_done))(xs->done_arg,xs->done_arg2);
        !           751: }
        !           752:
        !           753: /***********************************************\
        !           754: * A ecb (and hence a mbx-out is put onto the   *
        !           755: * free list.                                   *
        !           756: \***********************************************/
        !           757: ahb_free_ecb(unit,ecb, flags)
        !           758: struct ecb *ecb;
        !           759: {
        !           760:        unsigned int opri;
        !           761:
        !           762:        if(scsi_debug & PRINTROUTINES)
        !           763:                printf("ecb%d(0x%x)> ",unit,flags);
        !           764:        if (!(flags & SCSI_NOMASK))
        !           765:                opri = splbio();
        !           766:
        !           767:        ecb->next = ahb_data[unit].free_ecb;
        !           768:        ahb_data[unit].free_ecb = ecb;
        !           769:        ecb->flags = ECB_FREE;
        !           770:        /***********************************************\
        !           771:        * If there were none, wake abybody waiting for  *
        !           772:        * one to come free, starting with queued entries*
        !           773:        \***********************************************/
        !           774:        if (!ecb->next) {
        !           775:                wakeup(&ahb_data[unit].free_ecb);
        !           776:        }
        !           777:        if (!(flags & SCSI_NOMASK))
        !           778:                splx(opri);
        !           779: }
        !           780:
        !           781: /***********************************************\
        !           782: * Get a free ecb (and hence mbox-out entry)    *
        !           783: \***********************************************/
        !           784: struct ecb *
        !           785: ahb_get_ecb(unit,flags)
        !           786: {
        !           787:        unsigned opri;
        !           788:        struct ecb *rc;
        !           789:
        !           790:        if(scsi_debug & PRINTROUTINES)
        !           791:                printf("<ecb%d(0x%x) ",unit,flags);
        !           792:        if (!(flags & SCSI_NOMASK))
        !           793:                opri = splbio();
        !           794:        /***********************************************\
        !           795:        * If we can and have to, sleep waiting for one  *
        !           796:        * to come free                                  *
        !           797:        \***********************************************/
        !           798:        while ((!(rc = ahb_data[unit].free_ecb)) && (!(flags & SCSI_NOSLEEP)))
        !           799:        {
        !           800:                sleep(&ahb_data[unit].free_ecb, PRIBIO);
        !           801:        }
        !           802:        if (rc)
        !           803:        {
        !           804:                ahb_data[unit].free_ecb = rc->next;
        !           805:                rc->flags = ECB_ACTIVE;
        !           806:        }
        !           807:        if (!(flags & SCSI_NOMASK))
        !           808:                splx(opri);
        !           809:        return(rc);
        !           810: }
        !           811:
        !           812:
        !           813:
        !           814: /***********************************************\
        !           815: * Start the board, ready for normal operation  *
        !           816: \***********************************************/
        !           817: ahb_init(unit)
        !           818: int    unit;
        !           819: {
        !           820:        int     port = ahb_data[unit].baseport;
        !           821:        int     intdef;
        !           822:        int     spincount = FUDGE(delaycount) * 1000; /* 1 sec enough? */
        !           823:        int     i;
        !           824:        int     stport = port + G2STAT;
        !           825: #define        NO_NO 1
        !           826: #ifdef NO_NO
        !           827:        /***********************************************\
        !           828:        * reset board, If it doesn't respond, assume    *
        !           829:        * that it's not there.. good for the probe      *
        !           830:        \***********************************************/
        !           831:        outb(port + EBCTRL,CDEN);       /* enable full card */
        !           832:        outb(port + PORTADDR,PORTADDR_ENHANCED);
        !           833:
        !           834:        outb(port + G2CNTRL,G2CNTRL_HARD_RESET);
        !           835:        spinwait(1);
        !           836:        outb(port + G2CNTRL,0);
        !           837:        spinwait(10);
        !           838:        while(      ((inb(stport) & G2STAT_BUSY ))
        !           839:                && (spincount--));
        !           840:        if(spincount == -1)
        !           841:        {
        !           842:                if (ahb_debug & AHB_SHOWMISC)
        !           843:                        printf("ahb_init: No answer from bt742a board\n");
        !           844:                return(ENXIO);
        !           845:        }
        !           846:        i = inb(port + MBOXIN0) & 0xff;
        !           847:        if(i)
        !           848:        {
        !           849:                printf("self test failed, val = 0x%x\n",i);
        !           850:                return(EIO);
        !           851:        }
        !           852: #endif
        !           853:        while( inb(stport) &  G2STAT_INT_PEND)
        !           854:        {
        !           855:                printf(".");
        !           856:                outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
        !           857:                spinwait(10);
        !           858:        }
        !           859:        outb(port + EBCTRL,CDEN);       /* enable full card */
        !           860:        outb(port + PORTADDR,PORTADDR_ENHANCED);
        !           861:        /***********************************************\
        !           862:        * Assume we have a board at this stage          *
        !           863:        * setup dma channel from jumpers and save int   *
        !           864:        * level                                         *
        !           865:        \***********************************************/
        !           866: #ifdef __386BSD__
        !           867:        printf("ahb%d reading board settings, ",unit);
        !           868: #define        PRNT(x)
        !           869: #else  __386BSD__
        !           870:        printf("ahb%d:",unit);
        !           871: #define        PRNT(x) printf(x)
        !           872: #endif __386BSD__
        !           873:
        !           874:        intdef = inb(port + INTDEF);
        !           875:        switch(intdef & 0x07)
        !           876:        {
        !           877:        case    INT9:
        !           878:                ahb_data[unit].vect = 9;
        !           879:                PRNT("int=9 ");
        !           880:                break;
        !           881:        case    INT10:
        !           882:                ahb_data[unit].vect = 10;
        !           883:                PRNT("int=10 ");
        !           884:                break;
        !           885:        case    INT11:
        !           886:                ahb_data[unit].vect = 11;
        !           887:                PRNT("int=11 ");
        !           888:                break;
        !           889:        case    INT12:
        !           890:                ahb_data[unit].vect = 12;
        !           891:                PRNT("int=12 ");
        !           892:                break;
        !           893:        case    INT14:
        !           894:                ahb_data[unit].vect = 14;
        !           895:                PRNT("int=14 ");
        !           896:                break;
        !           897:        case    INT15:
        !           898:                ahb_data[unit].vect = 15;
        !           899:                PRNT("int=15 ");
        !           900:                break;
        !           901:        default:
        !           902:                printf("illegal int setting\n");
        !           903:                return(EIO);
        !           904:        }
        !           905:        outb(port + INTDEF ,(intdef | INTEN)); /* make sure we can interrupt */
        !           906:        /* who are we on the scsi bus */
        !           907:        ahb_data[unit].our_id = (inb(port + SCSIDEF) & HSCSIID);
        !           908:
        !           909:        /***********************************************\
        !           910:        * link up all our ECBs into a free list         *
        !           911:        \***********************************************/
        !           912:        for (i=0; i < NUM_CONCURRENT; i++)
        !           913:        {
        !           914:                ahb_data[unit].ecbs[i].next = ahb_data[unit].free_ecb;
        !           915:                ahb_data[unit].free_ecb = &ahb_data[unit].ecbs[i];
        !           916:                ahb_data[unit].free_ecb->flags = ECB_FREE;
        !           917:        }
        !           918:
        !           919:        /***********************************************\
        !           920:        * Note that we are going and return (to probe)  *
        !           921:        \***********************************************/
        !           922:        ahb_data[unit].flags |= AHB_INIT;
        !           923:        return( 0 );
        !           924: }
        !           925:
        !           926:
        !           927: #ifndef        min
        !           928: #define min(x,y) (x < y ? x : y)
        !           929: #endif min
        !           930:
        !           931:
        !           932: void ahbminphys(bp)
        !           933: struct buf *bp;
        !           934: {
        !           935: #ifdef MACH
        !           936: #if    !defined(OSF)
        !           937:        bp->b_flags |= B_NPAGES;                /* can support scat/gather */
        !           938: #endif /* defined(OSF) */
        !           939: #endif MACH
        !           940:        if(bp->b_bcount > ((AHB_NSEG-1) * PAGESIZ))
        !           941:        {
        !           942:                bp->b_bcount = ((AHB_NSEG-1) * PAGESIZ);
        !           943:        }
        !           944: }
        !           945:
        !           946: /***********************************************\
        !           947: * start a scsi operation given the command and *
        !           948: * the data address. Also needs the unit, target        *
        !           949: * and lu                                       *
        !           950: \***********************************************/
        !           951: int    ahb_scsi_cmd(xs)
        !           952: struct scsi_xfer *xs;
        !           953: {
        !           954:        struct  scsi_sense_data *s1,*s2;
        !           955:        struct ecb *ecb;
        !           956:        struct ahb_dma_seg *sg;
        !           957:        int     seg;    /* scatter gather seg being worked on */
        !           958:        int i   = 0;
        !           959:        int rc  =  0;
        !           960:        int     thiskv;
        !           961:        physaddr        thisphys,nextphys;
        !           962:        int     unit =xs->adapter;
        !           963:        int     bytes_this_seg,bytes_this_page,datalen,flags;
        !           964:        struct  iovec   *iovp;
        !           965:        int     s;
        !           966:        if(scsi_debug & PRINTROUTINES)
        !           967:                printf("ahb_scsi_cmd ");
        !           968:        /***********************************************\
        !           969:        * get a ecb (mbox-out) to use. If the transfer  *
        !           970:        * is from a buf (possibly from interrupt time)  *
        !           971:        * then we can't allow it to sleep               *
        !           972:        \***********************************************/
        !           973:        flags = xs->flags;
        !           974:        if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */
        !           975:        if(flags & ITSDONE)
        !           976:        {
        !           977:                printf("Already done?");
        !           978:                xs->flags &= ~ITSDONE;
        !           979:        }
        !           980:        if(!(flags & INUSE))
        !           981:        {
        !           982:                printf("Not in use?");
        !           983:                xs->flags |= INUSE;
        !           984:        }
        !           985:        if (!(ecb = ahb_get_ecb(unit,flags)))
        !           986:        {
        !           987:                xs->error = XS_DRIVER_STUFFUP;
        !           988:                return(TRY_AGAIN_LATER);
        !           989:        }
        !           990:
        !           991: cheat = ecb;
        !           992:        if(ahb_debug & AHB_SHOWECBS)
        !           993:                                printf("<start ecb(%x)>",ecb);
        !           994:        if(scsi_debug & SHOWCOMMANDS)
        !           995:        {
        !           996:                ahb_show_scsi_cmd(xs);
        !           997:        }
        !           998:        ecb->xs = xs;
        !           999:        /***********************************************\
        !          1000:        * If it's a reset, we need to do an 'immediate' *
        !          1001:        * command, and store it's ccb for later         *
        !          1002:        * if there is already an immediate waiting,     *
        !          1003:        * then WE must wait                             *
        !          1004:        \***********************************************/
        !          1005:        if(flags & SCSI_RESET)
        !          1006:        {
        !          1007:                ecb->flags |= ECB_IMMED;
        !          1008:                if(ahb_data[unit].immed_ecb)
        !          1009:                {
        !          1010:                        return(TRY_AGAIN_LATER);
        !          1011:                }
        !          1012:                ahb_data[unit].immed_ecb = ecb;
        !          1013:                if (!(flags & SCSI_NOMASK))
        !          1014:                {
        !          1015:                        s = splbio();
        !          1016:                        ahb_send_immed(unit,xs->targ,AHB_TARG_RESET);
        !          1017:                        ahb_add_timeout(ecb,xs->timeout);
        !          1018:                        splx(s);
        !          1019:                        return(SUCCESSFULLY_QUEUED);
        !          1020:                }
        !          1021:                else
        !          1022:                {
        !          1023:                        ahb_send_immed(unit,xs->targ,AHB_TARG_RESET);
        !          1024:                        /***********************************************\
        !          1025:                        * If we can't use interrupts, poll on completion*
        !          1026:                        \***********************************************/
        !          1027:                        if(scsi_debug & TRACEINTERRUPTS)
        !          1028:                                printf("wait ");
        !          1029:                        if( ahb_poll(unit,xs->timeout))
        !          1030:                        {
        !          1031:                                ahb_free_ecb(unit,ecb,flags);
        !          1032:                                xs->error = XS_TIMEOUT;
        !          1033:                                return(HAD_ERROR);
        !          1034:                        }
        !          1035:                        return(COMPLETE);
        !          1036:                }
        !          1037:        }
        !          1038:        /***********************************************\
        !          1039:        * Put all the arguments for the xfer in the ecb *
        !          1040:        \***********************************************/
        !          1041:        ecb->opcode = ECB_SCSI_OP;
        !          1042:        ecb->opt1 = ECB_SES|ECB_DSB|ECB_ARS;
        !          1043:        if(xs->datalen)
        !          1044:        {
        !          1045:                ecb->opt1 |= ECB_S_G;
        !          1046:        }
        !          1047:        ecb->opt2               =       xs->lu | ECB_NRB;
        !          1048:        ecb->cdblen             =       xs->cmdlen;
        !          1049:        ecb->sense              =       KVTOPHYS(&(ecb->ecb_sense));
        !          1050:        ecb->senselen           =       sizeof(ecb->ecb_sense);
        !          1051:        ecb->status             =       KVTOPHYS(&(ecb->ecb_status));
        !          1052:
        !          1053:        if(xs->datalen)
        !          1054:        { /* should use S/G only if not zero length */
        !          1055:                ecb->data       =       KVTOPHYS(ecb->ahb_dma);
        !          1056:                sg              =       ecb->ahb_dma ;
        !          1057:                seg             =       0;
        !          1058:                if(flags & SCSI_DATA_UIO)
        !          1059:                {
        !          1060:                        iovp = ((struct uio *)xs->data)->uio_iov;
        !          1061:                        datalen = ((struct uio *)xs->data)->uio_iovcnt;
        !          1062:                        xs->datalen = 0;
        !          1063:                        while ((datalen) && (seg < AHB_NSEG))
        !          1064:                        {
        !          1065:                                sg->addr = (physaddr)iovp->iov_base;
        !          1066:                                xs->datalen += sg->len = iovp->iov_len;
        !          1067:                                if(scsi_debug & SHOWSCATGATH)
        !          1068:                                        printf("(0x%x@0x%x)"
        !          1069:                                                        ,iovp->iov_len
        !          1070:                                                        ,iovp->iov_base);
        !          1071:                                sg++;
        !          1072:                                iovp++;
        !          1073:                                seg++;
        !          1074:                                datalen--;
        !          1075:                        }
        !          1076:                }
        !          1077:                else
        !          1078:                {
        !          1079:                        /***********************************************\
        !          1080:                        * Set up the scatter gather block               *
        !          1081:                        \***********************************************/
        !          1082:
        !          1083:                        if(scsi_debug & SHOWSCATGATH)
        !          1084:                                printf("%d @0x%x:- ",xs->datalen,xs->data);
        !          1085:                        datalen         =       xs->datalen;
        !          1086:                        thiskv          =       (int)xs->data;
        !          1087:                        thisphys        =       KVTOPHYS(thiskv);
        !          1088:
        !          1089:                        while ((datalen) && (seg < AHB_NSEG))
        !          1090:                        {
        !          1091:                                bytes_this_seg  = 0;
        !          1092:
        !          1093:                                /* put in the base address */
        !          1094:                                sg->addr = thisphys;
        !          1095:
        !          1096:                                if(scsi_debug & SHOWSCATGATH)
        !          1097:                                        printf("0x%x",thisphys);
        !          1098:
        !          1099:                                /* do it at least once */
        !          1100:                                nextphys = thisphys;
        !          1101:                                while ((datalen) && (thisphys == nextphys))
        !          1102:                                /*********************************************\
        !          1103:                                * This page is contiguous (physically) with   *
        !          1104:                                * the the last, just extend the length        *
        !          1105:                                \*********************************************/
        !          1106:                                {
        !          1107:                                        /* how far to the end of the page */
        !          1108:                                        nextphys= (thisphys & (~(PAGESIZ - 1)))
        !          1109:                                                                + PAGESIZ;
        !          1110:                                        bytes_this_page = nextphys - thisphys;
        !          1111:                                        /**** or the data ****/
        !          1112:                                        bytes_this_page = min(bytes_this_page
        !          1113:                                                                ,datalen);
        !          1114:                                        bytes_this_seg  += bytes_this_page;
        !          1115:                                        datalen         -= bytes_this_page;
        !          1116:
        !          1117:                                        /* get more ready for the next page */
        !          1118:                                        thiskv  = (thiskv & (~(PAGESIZ - 1)))
        !          1119:                                                                + PAGESIZ;
        !          1120:                                        if(datalen)
        !          1121:                                                thisphys = KVTOPHYS(thiskv);
        !          1122:                                }
        !          1123:                                /********************************************\
        !          1124:                                * next page isn't contiguous, finish the seg *
        !          1125:                                \********************************************/
        !          1126:                                if(scsi_debug & SHOWSCATGATH)
        !          1127:                                        printf("(0x%x)",bytes_this_seg);
        !          1128:                                sg->len = bytes_this_seg;
        !          1129:                                sg++;
        !          1130:                                seg++;
        !          1131:                        }
        !          1132:                } /*end of iov/kv decision */
        !          1133:                ecb->datalen = seg * sizeof(struct ahb_dma_seg);
        !          1134:                if(scsi_debug & SHOWSCATGATH)
        !          1135:                        printf("\n");
        !          1136:                if (datalen)
        !          1137:                { /* there's still data, must have run out of segs! */
        !          1138:                        printf("ahb_scsi_cmd%d: more than %d DMA segs\n",
        !          1139:                                unit,AHB_NSEG);
        !          1140:                        xs->error = XS_DRIVER_STUFFUP;
        !          1141:                        ahb_free_ecb(unit,ecb,flags);
        !          1142:                        return(HAD_ERROR);
        !          1143:                }
        !          1144:
        !          1145:        }
        !          1146:        else
        !          1147:        {       /* No data xfer, use non S/G values */
        !          1148:                ecb->data = (physaddr)0;
        !          1149:                ecb->datalen = 0;
        !          1150:        }
        !          1151:        ecb->chain = (physaddr)0;
        !          1152:        /***********************************************\
        !          1153:        * Put the scsi command in the ecb and start it  *
        !          1154:        \***********************************************/
        !          1155:        bcopy(xs->cmd, ecb->cdb, xs->cmdlen);
        !          1156:        /***********************************************\
        !          1157:        * Usually return SUCCESSFULLY QUEUED            *
        !          1158:        \***********************************************/
        !          1159:        if (!(flags & SCSI_NOMASK))
        !          1160:        {
        !          1161:                s = splbio();
        !          1162:                ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb);
        !          1163:                ahb_add_timeout(ecb,xs->timeout);
        !          1164:                splx(s);
        !          1165:                if(scsi_debug & TRACEINTERRUPTS)
        !          1166:                        printf("cmd_sent ");
        !          1167:                return(SUCCESSFULLY_QUEUED);
        !          1168:        }
        !          1169:        /***********************************************\
        !          1170:        * If we can't use interrupts, poll on completion*
        !          1171:        \***********************************************/
        !          1172:        ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb);
        !          1173:        if(scsi_debug & TRACEINTERRUPTS)
        !          1174:                printf("cmd_wait ");
        !          1175:        do
        !          1176:        {
        !          1177:                if(ahb_poll(unit,xs->timeout))
        !          1178:                {
        !          1179:                        if (!(xs->flags & SCSI_SILENT)) printf("cmd fail\n");
        !          1180:                        ahb_send_mbox(unit,OP_ABORT_ECB,xs->targ,ecb);
        !          1181:                        if(ahb_poll(unit,2000))
        !          1182:                        {
        !          1183:                                printf("abort failed in wait\n");
        !          1184:                                ahb_free_ecb(unit,ecb,flags);
        !          1185:                        }
        !          1186:                        xs->error = XS_DRIVER_STUFFUP;
        !          1187:                        splx(s);
        !          1188:                        return(HAD_ERROR);
        !          1189:                }
        !          1190:        } while (!(xs->flags & ITSDONE));/* something (?) else finished */
        !          1191:        splx(s);
        !          1192: scsi_debug = 0;ahb_debug = 0;
        !          1193:        if(xs->error)
        !          1194:        {
        !          1195:                return(HAD_ERROR);
        !          1196:        }
        !          1197:        return(COMPLETE);
        !          1198: }
        !          1199:
        !          1200: /*
        !          1201:  *                +----------+    +----------+    +----------+
        !          1202:  * ahb_soonest--->|    later |--->|     later|--->|     later|--->0
        !          1203:  *                | [Delta]  |    | [Delta]  |    | [Delta]  |
        !          1204:  *           0<---|sooner    |<---|sooner    |<---|sooner    |<---ahb_latest
        !          1205:  *                +----------+    +----------+    +----------+
        !          1206:  *
        !          1207:  *     ahb_furtherest = sum(Delta[1..n])
        !          1208:  */
        !          1209: ahb_add_timeout(ecb,time)
        !          1210: struct ecb     *ecb;
        !          1211: int    time;
        !          1212: {
        !          1213:        int     timeprev;
        !          1214:        struct ecb *prev;
        !          1215:        int     s = splbio();
        !          1216:
        !          1217:        if(prev = ahb_latest) /* yes, an assign */
        !          1218:        {
        !          1219:                timeprev = ahb_furtherest;
        !          1220:        }
        !          1221:        else
        !          1222:        {
        !          1223:                timeprev = 0;
        !          1224:        }
        !          1225:        while(prev && (timeprev > time))
        !          1226:        {
        !          1227:                timeprev -= prev->delta;
        !          1228:                prev = prev->sooner;
        !          1229:        }
        !          1230:        if(prev)
        !          1231:        {
        !          1232:                ecb->delta = time - timeprev;
        !          1233:                if( ecb->later = prev->later) /* yes an assign */
        !          1234:                {
        !          1235:                        ecb->later->sooner = ecb;
        !          1236:                        ecb->later->delta -= ecb->delta;
        !          1237:                }
        !          1238:                else
        !          1239:                {
        !          1240:                        ahb_furtherest = time;
        !          1241:                        ahb_latest = ecb;
        !          1242:                }
        !          1243:                ecb->sooner = prev;
        !          1244:                prev->later = ecb;
        !          1245:        }
        !          1246:        else
        !          1247:        {
        !          1248:                if( ecb->later = ahb_soonest) /* yes, an assign*/
        !          1249:                {
        !          1250:                        ecb->later->sooner = ecb;
        !          1251:                        ecb->later->delta -= time;
        !          1252:                }
        !          1253:                else
        !          1254:                {
        !          1255:                        ahb_furtherest = time;
        !          1256:                        ahb_latest = ecb;
        !          1257:                }
        !          1258:                ecb->delta = time;
        !          1259:                ecb->sooner = (struct ecb *)0;
        !          1260:                ahb_soonest = ecb;
        !          1261:        }
        !          1262:        splx(s);
        !          1263: }
        !          1264:
        !          1265: ahb_remove_timeout(ecb)
        !          1266: struct ecb     *ecb;
        !          1267: {
        !          1268:        int     s = splbio();
        !          1269:
        !          1270:        if(ecb->sooner)
        !          1271:        {
        !          1272:                ecb->sooner->later = ecb->later;
        !          1273:        }
        !          1274:        else
        !          1275:        {
        !          1276:                ahb_soonest = ecb->later;
        !          1277:        }
        !          1278:        if(ecb->later)
        !          1279:        {
        !          1280:                ecb->later->sooner = ecb->sooner;
        !          1281:                ecb->later->delta += ecb->delta;
        !          1282:        }
        !          1283:        else
        !          1284:        {
        !          1285:                ahb_latest = ecb->sooner;
        !          1286:                ahb_furtherest -= ecb->delta;
        !          1287:        }
        !          1288:        ecb->sooner = ecb->later = (struct ecb *)0;
        !          1289:        splx(s);
        !          1290: }
        !          1291:
        !          1292:
        !          1293: extern int     hz;
        !          1294: #define ONETICK 500 /* milliseconds */
        !          1295: #define SLEEPTIME ((hz * 1000) / ONETICK)
        !          1296: ahb_timeout(arg)
        !          1297: int    arg;
        !          1298: {
        !          1299:        struct  ecb  *ecb;
        !          1300:        int     unit;
        !          1301:        int     s       = splbio();
        !          1302:
        !          1303:        while( ecb = ahb_soonest )
        !          1304:        {
        !          1305:                if(ecb->delta <= ONETICK)
        !          1306:                /***********************************************\
        !          1307:                * It has timed out, we need to do some work     *
        !          1308:                \***********************************************/
        !          1309:                {
        !          1310:                        unit = ecb->xs->adapter;
        !          1311:                        printf("ahb%d:%d device timed out\n",unit
        !          1312:                                        ,ecb->xs->targ);
        !          1313:                        if(ahb_debug & AHB_SHOWECBS)
        !          1314:                                ahb_print_active_ecb();
        !          1315:
        !          1316:                        /***************************************\
        !          1317:                        * Unlink it from the queue              *
        !          1318:                        \***************************************/
        !          1319:                        ahb_remove_timeout(ecb);
        !          1320:
        !          1321:                        /***************************************\
        !          1322:                        * If it's immediate, don't try abort it *
        !          1323:                        \***************************************/
        !          1324:                        if(ecb->flags & ECB_IMMED)
        !          1325:                        {
        !          1326:                                ecb->xs->retries = 0; /* I MEAN IT ! */
        !          1327:                                ecb->flags |= ECB_IMMED_FAIL;
        !          1328:                                 ahb_done(unit,ecb,FAIL);
        !          1329:                                continue;
        !          1330:                        }
        !          1331:                        /***************************************\
        !          1332:                        * If it has been through before, then   *
        !          1333:                        * a previous abort has failed, don't    *
        !          1334:                        * try abort again                       *
        !          1335:                        \***************************************/
        !          1336:                        if(ecb->flags == ECB_ABORTED) /* abort timed out */
        !          1337:                        {
        !          1338:                                printf("AGAIN");
        !          1339:                                ecb->xs->retries = 0; /* I MEAN IT ! */
        !          1340:                                ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST;
        !          1341:                                ahb_done(unit,ecb,FAIL);
        !          1342:                        }
        !          1343:                        else    /* abort the operation that has timed out */
        !          1344:                        {
        !          1345:                                printf("\n");
        !          1346:                                ahb_send_mbox(unit,OP_ABORT_ECB,ecb->xs->targ,ecb);
        !          1347:                                        /* 2 secs for the abort */
        !          1348:                                ahb_add_timeout(ecb,2000 + ONETICK);
        !          1349:                                ecb->flags = ECB_ABORTED;
        !          1350:                        }
        !          1351:                }
        !          1352:                else
        !          1353:                /***********************************************\
        !          1354:                * It has not timed out, adjust and leave        *
        !          1355:                \***********************************************/
        !          1356:                {
        !          1357:                        ecb->delta -= ONETICK;
        !          1358:                        ahb_furtherest -= ONETICK;
        !          1359:                        break;
        !          1360:                }
        !          1361:        }
        !          1362:        splx(s);
        !          1363:        timeout(ahb_timeout,arg,SLEEPTIME);
        !          1364: }
        !          1365:
        !          1366: ahb_show_scsi_cmd(struct scsi_xfer *xs)
        !          1367: {
        !          1368:        u_char  *b = (u_char *)xs->cmd;
        !          1369:        int i = 0;
        !          1370:        if(!(xs->flags & SCSI_RESET))
        !          1371:        {
        !          1372:                printf("ahb%d:%d:%d-"
        !          1373:                        ,xs->adapter
        !          1374:                        ,xs->targ
        !          1375:                        ,xs->lu);
        !          1376:                while(i < xs->cmdlen )
        !          1377:                {
        !          1378:                        if(i) printf(",");
        !          1379:                        printf("%x",b[i++]);
        !          1380:                }
        !          1381:                printf("-\n");
        !          1382:        }
        !          1383:        else
        !          1384:        {
        !          1385:                printf("ahb%d:%d:%d-RESET-\n"
        !          1386:                        ,xs->adapter
        !          1387:                        ,xs->targ
        !          1388:                        ,xs->lu
        !          1389:                );
        !          1390:        }
        !          1391: }
        !          1392: ahb_print_ecb(ecb)
        !          1393: struct ecb *ecb;
        !          1394: {
        !          1395:        printf("ecb:%x op:%x cmdlen:%d senlen:%d\n"
        !          1396:                ,ecb
        !          1397:                ,ecb->opcode
        !          1398:                ,ecb->cdblen
        !          1399:                ,ecb->senselen);
        !          1400:        printf("        datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n"
        !          1401:                ,ecb->datalen
        !          1402:                ,ecb->ecb_status.ha_status
        !          1403:                ,ecb->ecb_status.targ_status
        !          1404:                ,ecb->delta
        !          1405:                ,ecb->flags);
        !          1406:        ahb_show_scsi_cmd(ecb->xs);
        !          1407: }
        !          1408:
        !          1409: ahb_print_active_ecb()
        !          1410: {
        !          1411:        struct  ecb *ecb;
        !          1412:        ecb = ahb_soonest;
        !          1413:
        !          1414:        while(ecb)
        !          1415:        {
        !          1416:                ahb_print_ecb(ecb);
        !          1417:                ecb = ecb->later;
        !          1418:        }
        !          1419:        printf("Furtherest = %d\n",ahb_furtherest);
        !          1420: }

CVSweb <webmaster@jp.NetBSD.org>